Tutorials

Lösen von Cloudflare Turnstile mit Python-Anfragen und CaptchaAI

Cloudflare Turnstile ersetzt herkömmliche CAPTCHAs auf Millionen von Websites. Dieser Leitfaden zeigt Ihnen, wie Sie Turnstile-Herausforderungen mit der requests-Bibliothek von Python und der API von CaptchaAI lösen – mit einer Erfolgsquote von 100 %.


Voraussetzungen

pip install requests

Sie benötigen:

  • Ein CaptchaAI-API-Schlüssel voncaptchaai.com
  • Die Zielseiten-URL
  • Der Turnstile-Sitekey

Schritt 1: Extrahieren Sie den Turnstile-Sitekey

import re
import requests

def extract_turnstile_sitekey(url):
    """Extract Cloudflare Turnstile sitekey from page HTML."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 Chrome/120.0.0.0",
        "Accept": "text/html,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9",
    }
    response = requests.get(url, headers=headers, timeout=15)

    patterns = [
        r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']',
        r"sitekey\s*:\s*['\"]([0-9x][A-Za-z0-9_-]+)['\"]",
        r"siteKey\s*[=:]\s*['\"]([0-9x][A-Za-z0-9_-]+)['\"]",
    ]

    for pattern in patterns:
        match = re.search(pattern, response.text)
        if match:
            return match.group(1)

    return None


sitekey = extract_turnstile_sitekey("https://example.com/signup")
print(f"Sitekey: {sitekey}")

Schritt 2: An CaptchaAI senden

import requests

API_KEY = "YOUR_API_KEY"

def submit_turnstile(sitekey, page_url):
    """Submit Turnstile solving task to CaptchaAI."""
    response = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": page_url,
        "json": 1,
    })

    data = response.json()

    if data.get("status") != 1:
        raise Exception(f"Submit failed: {data.get('request')}")

    return data["request"]


task_id = submit_turnstile("0x4AAAAAAAC3DHQhMMQ_Rxrg", "https://example.com/signup")
print(f"Task ID: {task_id}")

Schritt 3: Ergebnis abfragen

import time

def poll_result(task_id, timeout=120):
    """Poll CaptchaAI for the solved Turnstile token."""
    start = time.time()

    while time.time() - start < timeout:
        time.sleep(5)

        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

        if result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
            raise Exception("Turnstile could not be solved")

    raise TimeoutError("Solve timed out")


token = poll_result(task_id)
print(f"Token: {token[:50]}...")

Vollständiges Arbeitsbeispiel

import re
import time
import requests

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/signup"


def solve_turnstile(sitekey, page_url):
    """Full Turnstile solve: submit + poll."""
    # Submit
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": page_url,
        "json": 1,
    })

    data = submit.json()
    if data.get("status") != 1:
        raise Exception(f"Submit error: {data.get('request')}")

    task_id = data["request"]
    print(f"Task submitted: {task_id}")

    # Poll
    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Solve timed out")


# --- Main flow ---
session = requests.Session()
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 Chrome/120.0.0.0",
    "Accept": "text/html,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
})

# 1. Get page and extract sitekey
response = session.get(TARGET_URL, timeout=15)
match = re.search(r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', response.text)
if not match:
    raise ValueError("Turnstile sitekey not found")
sitekey = match.group(1)
print(f"Sitekey: {sitekey}")

# 2. Solve Turnstile
token = solve_turnstile(sitekey, TARGET_URL)
print(f"Token: {token[:50]}...")

# 3. Submit form with token
form_response = session.post(TARGET_URL, data={
    "cf-turnstile-response": token,
    "email": "user@example.com",
    "password": "SecurePass123",
})
print(f"Form status: {form_response.status_code}")

Handhabungsdrehkreuz mit Aktionsparameter

Einige Websites validieren den Parameter action serverseitig:

def solve_turnstile_with_action(sitekey, page_url, action):
    """Solve Turnstile that requires an action parameter."""
    submit = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "turnstile",
        "sitekey": sitekey,
        "pageurl": page_url,
        "action": action,  # Include the action from data-action attribute
        "json": 1,
    })

    data = submit.json()
    if data.get("status") != 1:
        raise Exception(f"Submit error: {data.get('request')}")

    task_id = data["request"]

    for _ in range(30):
        time.sleep(5)
        result = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY,
            "action": "get",
            "id": task_id,
            "json": 1,
        }).json()

        if result.get("status") == 1:
            return result["request"]

    raise TimeoutError("Solve timed out")

Muster für die Token-Übermittlung

Muster 1: POST mit cf-turnstile-response bilden

# Most common — Turnstile uses cf-turnstile-response field
response = session.post(form_url, data={
    "cf-turnstile-response": token,
    "email": "user@example.com",
})

Muster 2: JSON-API

response = session.post(api_url, json={
    "turnstileToken": token,
    "email": "user@example.com",
})

Muster 3: Benutzerdefinierter Feldname

# Some sites rename the field — check the form HTML
response = session.post(form_url, data={
    "cf-turnstile-response": token,
    "captcha_token": token,  # Custom duplicate field
    "action": "signup",
})

Produktionsreife Klasse

import re
import time
import requests

class TurnstileSolver:
    """Production-ready Turnstile solver with retry logic."""

    API_URL = "https://ocr.captchaai.com"

    def __init__(self, api_key, max_retries=3):
        self.api_key = api_key
        self.max_retries = max_retries

    def extract_sitekey(self, session, url):
        """Extract Turnstile sitekey from page."""
        response = session.get(url, timeout=15)
        match = re.search(
            r'data-sitekey=["\']([0-9x][A-Za-z0-9_-]+)["\']', response.text
        )
        return match.group(1) if match else None

    def solve(self, sitekey, page_url, action=None):
        """Solve Turnstile with retry logic. Returns token string."""
        for attempt in range(1, self.max_retries + 1):
            try:
                token = self._solve_once(sitekey, page_url, action)
                return token
            except TimeoutError:
                print(f"Attempt {attempt} timed out")
            except Exception as e:
                error_str = str(e)
                if "ERROR_ZERO_BALANCE" in error_str:
                    raise  # Don't retry billing errors
                if "ERROR_WRONG_USER_KEY" in error_str:
                    raise
                print(f"Attempt {attempt} failed: {e}")

        raise Exception(f"Failed after {self.max_retries} attempts")

    def _solve_once(self, sitekey, page_url, action=None):
        """Single solve attempt."""
        params = {
            "key": self.api_key,
            "method": "turnstile",
            "sitekey": sitekey,
            "pageurl": page_url,
            "json": 1,
        }
        if action:
            params["action"] = action

        submit = requests.post(f"{self.API_URL}/in.php", data=params, timeout=30)
        submit.raise_for_status()
        data = submit.json()

        if data.get("status") != 1:
            raise Exception(f"Submit error: {data.get('request')}")

        task_id = data["request"]

        for _ in range(30):
            time.sleep(5)
            result = requests.get(f"{self.API_URL}/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
                "json": 1,
            }, timeout=30).json()

            if result.get("status") == 1:
                return result["request"]
            if result.get("request") == "ERROR_CAPTCHA_UNSOLVABLE":
                raise Exception("CAPTCHA unsolvable")

        raise TimeoutError("Poll timed out")


# Usage
solver = TurnstileSolver("YOUR_API_KEY")
token = solver.solve("0x4AAAAAAAC3DHQhMMQ_Rxrg", "https://example.com/signup")

Fehlerbehebung

Symptom Ursache Beheben
Token erhalten, aber vom Formular abgelehnt Falscher Sitekey oder fehlende Aktion Sitekey erneut extrahieren, Aktion einschließen, falls vorhanden
„Sitekey nicht gefunden“ Turnstile geladen über JavaScript Verwenden Sie Selenium für dynamische Seiten
HTTP 403 vor dem Abrufen der Seite Cloudflare-BIC-Blockierungsanfrage Fügen Sie die richtigen Browser-Header hinzu
Das Lösen dauert >60 Sekunden Stau in der Warteschlange Zu Stoßzeiten normal, länger warten
Token funktioniert einmal und schlägt dann fehl Die Site benötigt pro Versuch ein neues Token Lösen Sie für jede Übermittlung ein neues Token

Häufig gestellte Fragen

Wie hoch ist die Erfolgsquote?

CaptchaAI erreicht bei Cloudflare Turnstile in allen Widget-Modi eine Erfolgsquote von 100 %.

Wie lange dauert die Lösung?

Die typische Lösungszeit beträgt 5–15 Sekunden. Turnstile ist im Allgemeinen schneller als reCAPTCHA.

Spielt der Turnstilemodus eine Rolle?

Nein. Der verwaltete, der nicht interaktive und der unsichtbare Modus verwenden alle denselben API-Aufruf. CaptchaAI behandelt Modusunterschiede intern.

Was ist, wenn die Seite sowohl Turnstile als auch reCAPTCHA enthält?

Ungewöhnlich, aber möglich. Identifizieren Sie, welches CAPTCHA das von Ihnen übermittelte Formular schützt, und lösen Sie dieses Problem. Sie verwenden unterschiedliche Antwortfeldnamen.


Zusammenfassung

Das Lösen von Cloudflare Turnstile mit Python requests erfordert drei Schritte: Extrahieren Sie den Sitekey aus dem Seiten-HTML und senden Sie ihn anCaptchaAIVerwenden Sie method=turnstile und fragen Sie nach dem Token. Senden Sie den Token als cf-turnstile-response in Ihren Formulardaten. CaptchaAI bietet eine Erfolgsquote von 100 % in allen Turnstilemodi.

Verwandte Leitfäden

Diskussionen (0)

Noch keine Kommentare.