Scrapy ist das beliebteste Python-Crawling-Framework. Diese Anleitung zeigt, wie Sie mithilfe einer benutzerdefinierten Middleware die CAPTCHA-Lösung CaptchaAI zu Ihren Spidern hinzufügen.
Anforderungen
| Anforderung | Einzelheiten |
|---|---|
| Python | 3,8+ |
| Scrapy | 2,5+ |
| Anfragen | Für CaptchaAI-API-Aufrufe |
| CaptchaAI API-Schlüssel | Holen Sie sich hier eins |
pip install scrapy requests
CaptchaAI Solver-Modul
Erstellen Sie captcha_solver.py in Ihrem Scrapy-Projektstamm:
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")
Scrapy-Middleware
Erstellen Sie middlewares.py:
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
Konfiguration der Einstellungen
Zu settings.py hinzufügen:
import os
CAPTCHAAI_API_KEY = os.environ.get("CAPTCHAAI_API_KEY")
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.CaptchaAIMiddleware": 560,
}
Spinnenbeispiel
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))
Versuchen Sie es erneut auf CAPTCHA-Seiten
Fügen Sie einen automatischen Wiederholungsversuch hinzu, wenn CAPTCHAs angezeigt werden:
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)
Die Spinne laufen lassen
export CAPTCHAAI_API_KEY="YOUR_API_KEY"
scrapy crawl products -o products.json
Fehlerbehebung
| Problem | Ursache | Lösung |
|---|---|---|
ValueError: CAPTCHAAI_API_KEY setting is required |
Fehlende Umgebungsvariable | Legen Sie CAPTCHAAI_API_KEY fest |
| CAPTCHA nicht erkannt | Andere HTML-Struktur | Regex-Muster in der Middleware aktualisieren |
TimeoutError beim Lösen |
Langsame Lösung oder Vernetzung | Timeout im Solver erhöhen |
| Spider wird nach dem Lösen blockiert | IP-basierte Blockierung | Fügen Sie Proxy-Rotations-Middleware hinzu |
FAQ
Kann ich dies mit Scrapy-Splash oder Scrapy-Playwright verwenden?
Ja. Bei mit JavaScript gerenderten Seiten funktioniert die Middleware auf die gleiche Weise – sie überprüft die endgültige HTML-Antwort auf CAPTCHA-Elemente.
Verlangsamt die Middleware das Crawlen?
Das Lösen von CAPTCHAs dauert 5–15 Sekunden pro Seite. Verwenden Sie CONCURRENT_REQUESTS, um während des Wartens andere Seiten zu crawlen. Nur Seiten mit CAPTCHAs verursachen Verzögerungen.
Wie gehe ich mit unterschiedlichen CAPTCHA-Typen pro Seite um?
Erweitern Sie die process_response-Methode der Middleware, um nach Turnstile, GeeTest oder anderen Typen zu suchen, und rufen Sie die entsprechende Solver-Methode auf.
Verwandte Leitfäden
- Captcha Scraping Python-Anleitung
- HTTPX + CaptchaAI-Integration
- aiohttp + CaptchaAI Asynchron
Diskussionen (0)
Beteiligen Sie sich an der Unterhaltung
Melden Sie sich an, um Ihre Meinung zu teilen.
AnmeldenNoch keine Kommentare.