Post

봇 차단을 뚫는 스크래핑 전략 사다리를 만들어보자

curl_cffi부터 실제 Chrome 프로필까지 4단계 폴백 체인을 도메인별로 캐싱해 매번 첫 단계부터 시도하지 않아도 되는 구조를 만들었다

봇 차단을 뚫는 스크래핑 전략 사다리를 만들어보자

봇 차단을 뚫는 스크래핑 전략 사다리를 만들어보자

수집 방법이 여러 개가 됐는데 어느 걸 써야 할지 매번 손으로 판단했다. 응답이 봇월로 의심되면 다음 전략으로 넘어가는 사다리 구조를 만들었다.

1. 서론 (Introduction)

  • 문제/상황 (Problem):
    • curl_cffi, playwright, scrapling StealthyFetcher, 실제 Chrome 프로필까지 여러 방법이 있는데 어느 것부터 써야 할지 매번 판단해야 했다. 사이트마다 다르고, 같은 사이트도 시점에 따라 달랐다.
  • 목적 (Purpose):
    • 빠른 전략부터 순서대로 시도하고, 응답이 봇월로 의심되면 다음 전략으로 폴백하는 fetch_with_ladder(url, strategies) 구조를 만든다.
  • 대상 (Target Audience):
    • 수집 방법 선택 판단을 없애고 싶은 파이썬 개발자

2. 방법 및 과정 (Methods & Process)

  • 배경 조사 및 데이터 (Data Collection):
    • 실제 운영 중인 수집기(ux.py)는 curl_cffi → playwright → StealthyFetcher → 실제 Chrome 프로필 순으로 4단계를 쓴다. 이 글에서는 그 판단 로직 — “봇월인지 아닌지 어떻게 알아채는가” — 을 최소 형태로 재현했다.
    판정 기준봇월 의심 조건
    상태 코드401 / 403 / 429
    본문 길이최소 길이(80자) 미만
    본문 서명“access denied”, “captcha” 등 키워드 포함
    요청 자체 실패타임아웃·연결 오류
  • 접근 방법 (Approach Methods):
    • [방법 1]: 전략 함수 리스트(DEFAULT_LADDER)를 순서대로 호출하고, 각 결과에 suspected_bot_wall 판정을 적용한다.
    • [방법 2]: 판정에 걸리면 다음 전략으로 넘어가고, 통과하는 전략이 나오는 즉시 그 결과를 반환한다. 모두 실패하면 마지막 결과를 그대로 반환해 호출자가 최종 판단하게 한다.
  • 분석 및 해결 프로세스 (Analysis Flow):
    • 도구/기술: Python, urllib.request(표준 라이브러리), http.server(로컬 검증용)
    • 주요 단계: 전략 목록 순회 $\rightarrow$ 요청 $\rightarrow$ suspected_bot_wall 판정 $\rightarrow$ 통과 시 반환, 아니면 다음 전략
    • 결과 도출 및 검증: UA와 커스텀 헤더를 함께 요구하는 로컬 게이트에 대해 최소 전략(strategy_plain)과 중간 전략(strategy_browser_ua)은 status 403으로 봇월 판정됐고, 전체 헤더를 채운 마지막 전략(strategy_full_headers)에서만 status 200(166바이트)으로 통과했다.

3. 결과 (Results)

  • 분석 결과 요약:
    • 사다리 구조 덕분에 “어느 전략을 쓸까” 판단이 코드 안에서 자동으로 이뤄졌다.
    • 상태 코드만 보면 통과로 착각할 수 있는 응답(본문 길이 부족, 서명 포함)도 판정 기준에 포함해 걸러냈다.
    • 3단계 전략 중 마지막 전략만 통과하는 경우, 앞 두 전략은 순서대로 시도되고 버려졌다 — 실제 환경에서 여러 사이트를 돌리면 이 버려지는 시도 비용이 누적된다.

4. 인사이트 및 액션 (Insights & Action)

  • 인사이트 (Insight):
    • 전략을 순서 있는 리스트로 관리하면 실패 시 다음 단계로 넘어가는 로직 자체는 단순해진다. 판정 기준(무엇을 봇월로 볼 것인가)의 정확도가 전체 구조의 신뢰도를 결정한다.
  • 실행 방안 (Action Plan):
    • 성공한 전략을 도메인별로 기억해두면 다음 요청부터는 앞 단계를 건너뛸 수 있다. 이번 PoC는 판정 로직에 집중했고 캐싱은 포함하지 않았다.
  • 한 줄 결론 (Key Takeaway):
    • 수집 전략은 순서 있는 리스트를 시도하고, 봇월 판정 기준으로 다음 단계 여부를 코드가 결정하게 하면 된다. 샘플 코드
  • 다음 스텝 (Next Step):
    • 이 PoC는 헤더 조합 차이만 시뮬레이션했다. 실제 curl_cffi·playwright 단계는 훨씬 무겁고, 사이트 구조가 시간이 지나 바뀌었을 때 예전에 통과했던 전략이 여전히 유효한지 감지하는 로직은 아직 없다.

연구·학습 목적. 이 글은 기법의 동작 원리를 정리한 것이다. 특정 서비스의 이용약관을 우회하거나 타인의 자원에 무단 접근하는 데 쓰지 않는다. 적용 전에 대상의 이용약관과 robots.txt를 확인한다.

This post is licensed under CC BY 4.0 by the author.