Scarnox · Blog

Captcha khi web scraping: vì sao xuất hiện và nên làm gì

Captcha xuất hiện khi scraping khi một trang quyết định một request trông như tự động. Các nguyên nhân thường gặp là gửi quá nhiều request trong thời gian ngắn, một địa chỉ IP có danh tiếng kém, thiếu tín hiệu trình duyệt, hoặc truy cập một trang được bảo vệ chặt hơn phần còn lại. Cách xử lý thực tế có ba bước, theo thứ tự này: giảm các nguyên nhân kích hoạt, phát hiện captcha trong code, và giải những captcha bạn không thể tránh. Hướng dẫn này bao quát từng bước và chỉ tới các hướng dẫn chi tiết cho phần còn lại.

Vì sao trang hiện captcha cho scraper

Một trang khó phân biệt người và script tại thời điểm một trang được yêu cầu, nên nó nhìn vào các mẫu. Một scraper thường lộ ra vì nó:

Chỉ một trong số này có thể đủ. Captcha là cách trang yêu cầu một bước giống người trước khi phục vụ thêm trang. Giảm mẫu thường giảm captcha, và điều đó rẻ hơn việc giải chúng.

Phát hiện captcha trong code

Trước khi giải bất cứ thứ gì, hãy kiểm tra xem trang bạn nhận được có phải là trang captcha hay không. Một kiểm tra đơn giản tìm đánh dấu của widget và đọc 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"])

Các chuỗi h-captcha và g-recaptcha chỉ là đánh dấu mà một trang dùng, nên đây là một tín hiệu chứ không phải đảm bảo. Nếu thiếu sitekey, xem cách tìm sitekey của captcha.

Giải khi bạn không thể tránh

Khi có widget PopularCaptcha trên trang và bạn có sitekey của nó, bạn có thể yêu cầu một token từ API Scarnox bằng một POST request và gửi nó trong trường h-captcha-response. Hàm đầy đủ, có xử lý lỗi, nằm trong giải captcha từ Python chỉ với một request. Dùng token ngay, vì nó hết hạn sau khoảng hai phút. Các chi tiết về thời gian nằm trong token captcha hết hạn.

Hỗ trợ hiện tại của Scarnox là PopularCaptcha, có proxy và không có proxy. reCAPTCHA v2 và v3, Cloudflare Turnstile, GeeTest, AWS WAF và Arkose sắp ra mắt. Nếu mục tiêu của bạn dùng một loại trong số đó, các hướng dẫn captcha giải thích các lựa chọn chung, nhưng đừng xây dựng luồng production trên một lần giải chưa hoạt động.

Quyết định cho từng trang bị chặn

Khi scraper của bạn gặp captcha, một thứ tự quyết định đơn giản giữ công việc trung thực và giữ khối lượng request thấp:

  1. Có nguồn dữ liệu nào bạn có thể dùng thay thế không? Nếu một API, feed hoặc bản xuất cung cấp các trường bạn cần, hãy chuyển sang đó và ngừng yêu cầu trang này.
  2. robots.txt có cho phép đường dẫn không? Nếu không, bỏ qua nó. Đừng giải captcha trên một trang mà bạn đã được yêu cầu để yên.
  3. Bạn có gửi quá nhiều, quá nhanh không? Tạm dừng lâu hơn, giảm tốc độ và kiểm tra lại sau. Nhiều captcha tự hết khi nhịp độ chậm lại.
  4. Captcha có phải là loại đang hoạt động không? Nếu là PopularCaptcha, lần giải trong hướng dẫn này áp dụng. Nếu là loại sắp ra mắt, hãy giữ công việc tạm dừng và theo dõi thời điểm phát hành.
  5. Trang có phải là trang bạn được phép tự động hóa không? Nếu câu trả lời chưa rõ, hãy hỏi chủ trang trước khi tiếp tục.

Bước thứ tư là bước hay bị bỏ qua nhất. Một bộ giải chỉ hữu ích khi loại captcha được hỗ trợ, và một công việc cứ thử lại loại không được hỗ trợ sẽ lãng phí thời gian và request.

Xử lý captcha trong một công việc, không trong vòng lặp

Đặt lần giải trong đoạn code cần token, để công việc có thể ghi log từng captcha, dừng khi một trang liên tục thất bại, và chuyển sang trang khác. Một vòng lặp không giới hạn cứ yêu cầu một trang captcha là cách nhanh nhất để tường lửa của trang chặn địa chỉ của bạn vĩnh viễn.

Theo dõi những gì thất bại

Giữ số lượng trang trả về captcha, nhóm theo URL và theo khung giờ trong ngày. Một captcha chỉ xuất hiện ở một phần của trang, hoặc chỉ sau một số request nhất định, cho bạn biết nguyên nhân kích hoạt nằm ở đâu. Thông tin đó hữu ích hơn một bộ giải nhanh hơn, vì nó cho bạn biết cần thay đổi gì.

Những việc không nên làm

Scrape có trách nhiệm

Bước tiếp theo