웹 스크래핑 captcha: 왜 나타나고 무엇을 할 것인가
스크래핑 중 captcha는 사이트가 요청이 자동화된 것처럼 보인다고 판단할 때 나타납니다. 흔한 원인은 짧은 시간에 너무 많은 요청, 평판이 나쁜 IP 주소, 브라우저 신호 누락, 또는 사이트가 다른 곳보다 더 엄격하게 보호하는 페이지에 대한 접근입니다. 실무적인 대응은 이 순서로 세 단계입니다. 원인을 줄이고, 코드에서 captcha를 감지하고, 피할 수 없는 captcha를 풉니다. 이 가이드는 각 단계를 다루고, 나머지는 상세 가이드로 안내합니다.
사이트가 스크래퍼에게 captcha를 보이는 이유
사이트는 페이지를 요청하는 순간 사람과 스크립트를 구별할 방법이 거의 없으므로, 패턴을 봅니다. 스크래퍼는 보통 다음과 같은 이유로 눈에 띕니다.
- 어떤 사람이 클릭하는 것보다 빠르게 요청을 보냅니다.
- 멈추지 않고 같은 경로를 반복합니다.
- 가정용 네트워크가 아니라 데이터센터 주소에서 옵니다.
- 흔한 브라우저와 맞지 않는 헤더를 보냅니다.
- 요청 사이에 쿠키나 세션 상태를 유지하지 않습니다.
이 중 하나만으로도 충분할 수 있습니다. captcha는 사이트가 더 많은 페이지를 제공하기 전에 사람 같은 단계를 요구하는 방식입니다. 패턴을 줄이면 보통 captcha도 줄어들며, 이는 풀이보다 저렴합니다.
코드에서 captcha 감지하기
무엇이든 풀기 전에, 받은 페이지가 정말 captcha 페이지인지 확인하세요. 간단한 테스트는 위젯 마크업을 찾고 sitekey를 읽습니다.
import re
import requests
SITEKEY_RE = re.compile(r'data-sitekey="([0-9a-f-]{36})"')
def fetch(url: str) -> dict:
resp = requests.get(
url,
timeout=30,
headers={"User-Agent": "ExampleBot/1.0 (+https://example.com/bot)"},
)
html = resp.text
if "h-captcha" in html or "g-recaptcha" in html:
match = SITEKEY_RE.search(html)
return {"captcha": True, "sitekey": match.group(1) if match else None, "html": html}
return {"captcha": False, "sitekey": None, "html": html}
page = fetch("https://example.com/search?q=shoes")
if page["captcha"]:
print("captcha found, sitekey:", page["sitekey"])
h-captcha와 g-recaptcha 문자열은 페이지가 사용하는 마크업일 뿐이므로, 이것은 보장이 아니라 신호입니다. sitekey가 없다면 captcha sitekey 찾는 방법을 참고하세요.
피할 수 없을 때 풀기
페이지에 PopularCaptcha 위젯이 있고 sitekey를 알고 있다면, Scarnox API에 POST 요청 한 번으로 토큰을 요청하고 h-captcha-response 필드에 제출할 수 있습니다. 오류 처리를 포함한 전체 함수는 Python에서 요청 한 번으로 captcha 풀기에 있습니다. 토큰은 약 2분 뒤에 만료되므로 바로 사용하세요. 타이밍 세부 사항은 captcha 토큰 만료에 있습니다.
Scarnox의 현재 실시간 지원은 PopularCaptcha이며, 프록시리스와 자체 프록시 두 방식 모두 가능합니다. reCAPTCHA v2와 v3, Cloudflare Turnstile, GeeTest, AWS WAF, Arkose는 출시 예정입니다. 대상이 그중 하나를 쓴다면, captcha 가이드가 일반적인 선택지를 설명하지만, 실시간이 아닌 풀이 위에 운영 흐름을 만들지는 마세요.
차단된 페이지마다의 결정 흐름
스크래퍼가 captcha에 부딪히면, 간단한 결정 순서가 작업을 정직하게 유지하고 요청량을 낮게 유지합니다.
- 대신 사용할 데이터 출처가 있나요? 필요한 필드를 API, 피드, 또는 내보내기가 제공한다면, 그쪽으로 바꾸고 그 페이지 요청은 멈추세요.
- robots.txt가 그 경로를 허용하나요? 아니라면 건너뛰세요. 떠나 달라고 요청받은 페이지의 captcha를 풀지 마세요.
- 너무 많이, 너무 빨리 보냈나요? 더 오래 멈추고, 속도를 낮추고, 나중에 다시 확인하세요. 많은 captcha는 더 느린 속도에서 사라집니다.
- 이 captcha는 실시간 유형인가요? PopularCaptcha라면 이 가이드의 풀이가 적용됩니다. 출시 예정인 유형이라면, 작업을 멈춰 두고 출시를 모니터링하세요.
- 이 페이지는 자동화가 허용된 곳인가요? 확실하지 않다면, 계속하기 전에 사이트 소유자에게 물어보세요.
네 번째 단계가 가장 자주 건너뛰어집니다. 풀이기는 captcha 유형이 지원될 때만 쓸모가 있으며, 지원되지 않는 유형을 계속 재시도하는 작업은 시간과 요청을 낭비합니다.
루프가 아니라 작업 안에서 captcha 처리하기
토큰이 필요한 코드 경로 안에 풀이를 넣으세요. 그래야 작업이 각 captcha를 기록하고, 페이지가 계속 실패하면 멈추고, 다음으로 넘어갈 수 있습니다. captcha 페이지를 계속 요청하는 제한 없는 루프는 사이트의 방화벽이 여러분의 주소를 영구적으로 차단하게 만드는 가장 빠른 길입니다.
실패하는 것을 모니터링하기
captcha를 반환한 페이지 수를 URL별, 그리고 하루 중 시간대별로 세어 두세요. 사이트의 한 구역에서만, 또는 일정 횟수의 요청 뒤에만 captcha가 나타난다면, 그것이 원인이 어디에 있는지 알려 줍니다. 그 정보는 더 빠른 솔버보다 유용합니다. 무엇을 바꿔야 할지 보여 주기 때문입니다.
하지 말아야 할 것
- 사이트의 제한을 피하려고 많은 IP 주소를 돌리지 마세요. 회피이며, 속도를 늦추라는 요청을 싸움으로 바꿉니다.
- 사용 권한이 없는 자격 증명으로 로그인 뒤의 페이지를 스크래핑하지 마세요.
- 계정을 만들거나, 스팸을 게시하거나, 한정 상품을 사기 위해 captcha를 풀지 마세요.
책임 있게 스크래핑하기
- 시작하기 전에 사이트의
robots.txt와 이용 약관을 읽으세요. 허용되지 않은 경로와 크롤 지연을 존중하세요. - User-Agent에 봇을 정직하게 밝히고, 연락할 방법을 적으세요.
- 요청 빈도를 낮게 유지하세요. captcha는 종종 사이트가 속도를 늦추라고 요청하는 것입니다.
- 사이트가 요청하면 멈추고, 존중하라고 들은 차단을 우회하지 마세요.
- 적용되는 개인정보 규칙에 따라 개인 데이터를 다루고, 필요한 것만 수집하세요.