Entegrasyonlar

Scrapy + CaptchaAI Entegrasyon Kılavuzu

Scrapy, en popüler Python tarama çerçevesidir. Bu kılavuz, özel bir ara yazılım kullanarak CaptchaAI CAPTCHA çözümünü örümceklerinize nasıl ekleyeceğinizi gösterir.

Gereksinimler

Gereksinim Ayrıntılar
Python 3.8+
yıpratıcı 2,5+
istekler CaptchaAI API çağrıları için
CaptchaAI API anahtarı Buradan bir tane alın
pip install scrapy requests

CaptchaAI Çözücü Modülü

Scrapy proje kökünüzde captcha_solver.py oluşturun:

import requests
import time


class CaptchaAISolver:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://ocr.captchaai.com"

    def solve_recaptcha(self, site_key, page_url, timeout=300):
        resp = requests.get(f"{self.base_url}/in.php", params={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": site_key,
            "pageurl": page_url,
        })

        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit failed: {resp.text}")

        task_id = resp.text.split("|")[1]
        deadline = time.time() + timeout

        while time.time() < deadline:
            time.sleep(5)
            result = requests.get(f"{self.base_url}/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
            })

            if result.text == "CAPCHA_NOT_READY":
                continue
            if result.text.startswith("OK|"):
                return result.text.split("|", 1)[1]
            raise Exception(f"Solve failed: {result.text}")

        raise TimeoutError(f"Task {task_id} timed out")

    def solve_image(self, image_base64, timeout=120):
        resp = requests.get(f"{self.base_url}/in.php", params={
            "key": self.api_key,
            "method": "base64",
            "body": image_base64,
        })

        if not resp.text.startswith("OK|"):
            raise Exception(f"Submit failed: {resp.text}")

        task_id = resp.text.split("|")[1]
        deadline = time.time() + timeout

        while time.time() < deadline:
            time.sleep(5)
            result = requests.get(f"{self.base_url}/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
            })

            if result.text == "CAPCHA_NOT_READY":
                continue
            if result.text.startswith("OK|"):
                return result.text.split("|", 1)[1]
            raise Exception(f"Solve failed: {result.text}")

        raise TimeoutError(f"Task {task_id} timed out")

Kazıyıcı Ara Yazılım

middlewares.py'yi oluşturun:

import base64
import re
from scrapy import signals
from scrapy.http import HtmlResponse
from captcha_solver import CaptchaAISolver


class CaptchaAIMiddleware:
    """Scrapy downloader middleware that detects and solves CAPTCHAs."""

    def __init__(self, api_key):
        self.solver = CaptchaAISolver(api_key)

    @classmethod
    def from_crawler(cls, crawler):
        api_key = crawler.settings.get("CAPTCHAAI_API_KEY")
        if not api_key:
            raise ValueError("CAPTCHAAI_API_KEY setting is required")
        return cls(api_key)

    def process_response(self, request, response, spider):
        # Check for reCAPTCHA on the page
        site_key = self._find_recaptcha_key(response.text)
        if site_key:
            spider.logger.info(f"reCAPTCHA detected on {response.url}")
            token = self.solver.solve_recaptcha(site_key, response.url)
            request.meta["captcha_token"] = token
            spider.logger.info("CAPTCHA solved successfully")

        # Check for image CAPTCHA
        captcha_img = self._find_image_captcha(response)
        if captcha_img:
            spider.logger.info(f"Image CAPTCHA detected on {response.url}")
            text = self.solver.solve_image(captcha_img)
            request.meta["captcha_text"] = text
            spider.logger.info(f"Image CAPTCHA solved: {text}")

        return response

    def _find_recaptcha_key(self, html):
        match = re.search(
            r'data-sitekey=["\']([A-Za-z0-9_-]+)["\']', html
        )
        return match.group(1) if match else None

    def _find_image_captcha(self, response):
        img = response.css("img#captcha-image::attr(src)").get()
        if img and img.startswith("data:image"):
            return img.split(",", 1)[1]
        return None

Ayarlar Yapılandırması

settings.py'ye ekle:

import os

CAPTCHAAI_API_KEY = os.environ.get("CAPTCHAAI_API_KEY")

DOWNLOADER_MIDDLEWARES = {
    "myproject.middlewares.CaptchaAIMiddleware": 560,
}

Örümcek Örneği

import scrapy


class ProductSpider(scrapy.Spider):
    name = "products"
    start_urls = ["https://example.com/products"]

    def parse(self, response):
        # If CAPTCHA was solved, the token is in meta
        token = response.meta.get("captcha_token")
        if token:
            # Resubmit the page with the token
            yield scrapy.FormRequest(
                url=response.url,
                formdata={"g-recaptcha-response": token},
                callback=self.parse_products,
            )
        else:
            yield from self.parse_products(response)

    def parse_products(self, response):
        for product in response.css(".product-item"):
            yield {
                "name": product.css("h2::text").get(),
                "price": product.css(".price::text").get(),
                "url": response.urljoin(
                    product.css("a::attr(href)").get()
                ),
            }

        next_page = response.css("a.next-page::attr(href)").get()
        if next_page:
            yield scrapy.Request(response.urljoin(next_page))

CAPTCHA Sayfalarında yeniden deneyin

CAPTCHA'lar göründüğünde otomatik yeniden denemeyi ekleyin:

class CaptchaRetryMiddleware:
    """Retry requests that return CAPTCHA challenge pages."""

    max_retries = 3

    def process_response(self, request, response, spider):
        if self._is_captcha_page(response):
            retries = request.meta.get("captcha_retries", 0)
            if retries < self.max_retries:
                request.meta["captcha_retries"] = retries + 1
                spider.logger.info(
                    f"CAPTCHA page detected, retry {retries + 1}"
                )
                return request.copy()

        return response

    def _is_captcha_page(self, response):
        indicators = [
            "g-recaptcha",
            "cf-turnstile",
            "captcha-image",
            "Please verify you are human",
        ]
        return any(ind in response.text for ind in indicators)

Örümcek'i Çalıştırmak

export CAPTCHAAI_API_KEY="YOUR_API_KEY"
scrapy crawl products -o products.json

Sorun giderme

Sorun Sebep Düzeltme
ValueError: CAPTCHAAI_API_KEY setting is required Env var eksik CAPTCHAAI_API_KEY'yi ayarlayın
CAPTCHA algılanmadı Farklı HTML yapısı Ara yazılımdaki normal ifade modelini güncelleme
Çözerken TimeoutError Yavaş çözüm veya ağ Çözücüde zaman aşımını artırın
Örümcek çözdükten sonra engelleniyor IP tabanlı engelleme Proxy rotasyon ara yazılımı ekleme

SSS

Bunu Scrapy-Splash veya Scrapy-Playwright ile kullanabilir miyim?

Evet. JavaScript ile oluşturulan sayfalar için ara yazılım aynı şekilde çalışır; CAPTCHA öğeleri için son HTML yanıtını denetler.

Ara yazılım taramayı yavaşlatıyor mu?

CAPTCHA çözme sayfa başına 5-15 saniye sürer. Beklerken diğer sayfaları taramak için CONCURRENT_REQUESTS kullanın. Yalnızca CAPTCHA içeren sayfalar gecikmelere neden olur.

Sayfa başına farklı CAPTCHA türlerini nasıl yönetirim?

Turnstile, GeeTest veya diğer türleri kontrol etmek için ara yazılımın process_response yöntemini genişletin ve uygun çözücü yöntemini çağırın.

İlgili Kılavuzlar

Bu makale için yorumlar devre dışı bırakılmıştır.