应用场景

抓取受验证码保护的网站

大多数高价值网站都使用验证码作为反机器人防御的一部分。本指南涵盖了使用 CaptchaAI 可靠地抓取这些网站的策略,包括如何识别验证码类型、自动解决它们以及构建弹性抓取器。

常见验证码实施

验证码 使用地点 CaptchaAI方法
reCAPTCHA v2 登录表单、搜索页面 method=userrecaptcha
reCAPTCHA v3 任何页面的后台评分 method=userrecaptcha&version=v3
Cloudflare Turnstile Cloudflare 背后的网站 method=turnstile
Cloudflare 验证流程 整页 Cloudflare 块 method=cloudflare_challenge
图片/OCR 验证码 旧网站、亚马逊 method=base64
验证码 注重隐私的网站 method=hcaptcha

策略 1:按需检测并解决

最可靠的方法 - 正常抓取并仅在验证码出现时解决它们:

import requests
import time
from bs4 import BeautifulSoup

API_KEY = "YOUR_API_KEY"

class ProtectedScraper:
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
        })

    def scrape(self, url):
        resp = self.session.get(url)

        # Check for CAPTCHA
        if self._has_captcha(resp.text):
            resp = self._handle_captcha(resp.text, url)

        return resp.text

    def _has_captcha(self, html):
        indicators = ["g-recaptcha", "cf-turnstile", "h-captcha", "captcha"]
        return any(ind in html.lower() for ind in indicators)

    def _handle_captcha(self, html, url):
        soup = BeautifulSoup(html, "html.parser")

        # reCAPTCHA v2
        rc = soup.find("div", class_="g-recaptcha")
        if rc:
            token = self._solve_recaptcha(rc["data-sitekey"], url)
            return self.session.post(url, data={"g-recaptcha-response": token})

        # Cloudflare Turnstile
        ts = soup.find("div", class_="cf-turnstile")
        if ts:
            token = self._solve_turnstile(ts["data-sitekey"], url)
            return self.session.post(url, data={"cf-turnstile-response": token})

        raise Exception("Unknown CAPTCHA type")

    def _solve_recaptcha(self, site_key, page_url):
        resp = requests.get("https://ocr.captchaai.com/in.php", params={
            "key": API_KEY, "method": "userrecaptcha",
            "googlekey": site_key, "pageurl": page_url
        })
        return self._poll(resp.text.split("|")[1])

    def _solve_turnstile(self, site_key, page_url):
        resp = requests.get("https://ocr.captchaai.com/in.php", params={
            "key": API_KEY, "method": "turnstile",
            "sitekey": site_key, "pageurl": page_url
        })
        return self._poll(resp.text.split("|")[1])

    def _poll(self, task_id):
        for _ in range(60):
            time.sleep(5)
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": API_KEY, "action": "get", "id": task_id
            })
            if result.text == "CAPCHA_NOT_READY": continue
            if result.text.startswith("OK|"): return result.text.split("|")[1]
            raise Exception(result.text)
        raise TimeoutError()

# Usage
scraper = ProtectedScraper()
html = scraper.scrape("https://example.com/data")

策略 2:预求解已知验证码页面

如果您知道哪些页面始终具有验证码,请先行解决:

def scrape_known_captcha_page(url, site_key):
    # Solve before even loading the page
    token = solve_recaptcha(site_key, url)

    # Submit directly with token
    resp = requests.post(url, data={
        "g-recaptcha-response": token,
        "query": "search term"
    })
    return resp.text

策略 3:受 Cloudflare 保护的站点

Cloudflare 背后的站点通常需要 qa_session_cookie cookie:

def get_cloudflare_clearance(url, proxy):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "cloudflare_challenge",
        "pageurl": url,
        "proxy": proxy,
        "proxytype": "HTTP"
    })
    task_id = resp.text.split("|")[1]

    for _ in range(60):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get", "id": task_id
        })
        if result.text == "CAPCHA_NOT_READY": continue
        if "qa_session_cookie" in result.text:
            # Parse qa_session_cookie and user_agent from response
            return result.text
    raise TimeoutError()

多页抓取模式

def scrape_multiple_pages(base_url, site_key, pages):
    scraper = ProtectedScraper()
    results = []

    for page in pages:
        url = f"{base_url}?page={page}"
        try:
            html = scraper.scrape(url)
            soup = BeautifulSoup(html, "html.parser")
            items = soup.find_all("div", class_="item")
            results.extend([item.text.strip() for item in items])
            print(f"Page {page}: {len(items)} items")
        except Exception as e:
            print(f"Page {page} failed: {e}")

        time.sleep(random.uniform(2, 5))

    return results

故障排除

问题 处理方式
验证码出现在每个页面上 使用代理;降低请求率
解决后token被拒绝 令牌可能已过期; 120秒内使用
尽管有权限,Cloudflare 仍会阻止 对所有请求使用相同的代理和用户代理
解决后网站返回不同页面 检查是否有其他重定向或 cookie

常问问题

哪些网站最难抓取?

使用 Cloudflare Enterprise、PerimeterX 或 Akamai Bot Manager 的站点最具挑战性。 CaptchaAI 处理其验证码组件;与隐形浏览器和代理结合以获得最佳效果。

我可以抓取需要登录的网站吗?

是的。首先登录(解决任何登录验证码),维护会话 cookie,然后抓取经过身份验证的页面。 CaptchaAI 在任何阶段处理验证码。

如何处理 JavaScript 渲染的页面?

使用 Selenium、Puppeteer 或 Playwright 渲染 JavaScript,然后提取验证码参数并通过 CaptchaAI 进行求解。看硒验证码处理。

相关指南

该文章已禁用评论。