Anwendungsfälle

Selenium CAPTCHA-Handhabung mit Python und CaptchaAI

Ein CAPTCHA lösen Sie in einem Selenium-Skript nicht im Browser selbst, sondern über eine externe API: Sie lesen den Sitekey und die Seiten-URL aus dem DOM aus, senden beide an CaptchaAI und tragen das zurückgegebene Token in das Formular ein. Selenium steuert weiterhin die Seite, das eigentliche Lösen läuft serverseitig. Dieser Leitfaden zeigt den kompletten Ablauf in Python – von der Einrichtung über den Solver bis zu reCAPTCHA v2/v3 und Cloudflare Turnstile.

Voraussetzungen

Voraussetzung Details
Python 3.7+ Mit installiertem Pip
Selenium pip install selenium
Chrome + ChromeDriver Passende Versionen
requests pip install requests
CaptchaAI API-Schlüssel Aus captchaai.com

So löst CaptchaAI CAPTCHAs neben Selenium

Der Ablauf trennt sauber, was der Browser tut und was die API tut:

  1. Selenium lädt die Zielseite
  2. Ihr Skript liest den CAPTCHA-Sitekey aus dem Seiten-DOM aus
  3. CaptchaAI löst das CAPTCHA anhand von Sitekey und Seiten-URL
  4. Ihr Skript fügt das Token in die Seite ein und sendet das Formular ab

Das CAPTCHA wird serverseitig von CaptchaAI gelöst – Selenium interagiert nie direkt mit dem CAPTCHA-Widget. Das hält Ihren Automatisierungscode schlank: Sie brauchen keine Bilderkennung und keine Klick-Logik im Browser, sondern nur zwei Werte aus dem DOM und einen HTTP-Aufruf.

Schritt 1: Selenium einrichten

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")

driver = webdriver.Chrome(options=options)

Das AutomationControlled-Flag sorgt für realistischeres Browser-Verhalten und reduziert einfache Automatisierungssignale. Für eine robustere Konfiguration ergänzen Sie:

options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)

Schritt 2: Den CAPTCHA-Solver aufbauen

Die folgende Funktion übernimmt beide Phasen des API-Aufrufs: Sie übermittelt die Aufgabe an in.php und fragt anschließend das Ergebnis an res.php ab, bis das Token bereitsteht. Das Polling läuft in festen Intervallen und bricht nach einem Timeout ab.

import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_recaptcha_v2(site_key, page_url):
    """Solve reCAPTCHA v2 using CaptchaAI API."""
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": 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]

    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(f"Solve failed: {result.text}")

    raise TimeoutError("CAPTCHA solve timed out")

Schritt 3: Sitekey auslesen und lösen

Selenium wartet, bis das reCAPTCHA-Element im DOM steht, liest das Attribut data-sitekey aus und übergibt es zusammen mit der aktuellen URL an den Solver:

# Navigate to the target page
driver.get("https://example.com/login")

# Wait for the reCAPTCHA to load
wait = WebDriverWait(driver, 10)
recaptcha = wait.until(
    EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
)

# Extract the site key
site_key = recaptcha.get_attribute("data-sitekey")
page_url = driver.current_url

print(f"Site key: {site_key}")
print(f"Page URL: {page_url}")

# Solve the CAPTCHA
token = solve_recaptcha_v2(site_key, page_url)
print(f"Token received: {token[:50]}...")

Wichtig ist hier der Klassenname g-recaptcha: An ihm hängt das data-sitekey-Attribut. Lädt die Seite das Widget erst per JavaScript nach, erhöhen Sie das Timeout im WebDriverWait.

Schritt 4: Token einfügen und Formular absenden

Das gelöste Token gehört in das versteckte Feld g-recaptcha-response. Nutzt die Seite eine Callback-Funktion statt eines normalen Submits, lösen Sie diese zusätzlich aus:

# Inject the token into the reCAPTCHA response field
driver.execute_script(f"""
    document.getElementById('g-recaptcha-response').innerHTML = '{token}';
    document.getElementById('g-recaptcha-response').style.display = '';
""")

# If the form uses a callback function, trigger it
driver.execute_script(f"""
    if (typeof ___grecaptcha_cfg !== 'undefined') {{
        Object.keys(___grecaptcha_cfg.clients).forEach(function(key) {{
            var client = ___grecaptcha_cfg.clients[key];
            if (client.callback) client.callback('{token}');
        }});
    }}
""")

# Submit the form
driver.find_element(By.CSS_SELECTOR, "form").submit()

# Wait for navigation
wait.until(EC.url_changes(page_url))
print(f"Success! Now on: {driver.current_url}")

Der url_changes-Check dient als schlichte Erfolgsprüfung: Wechselt die Seite, wurde das Token akzeptiert. Bleibt die URL stehen, prüfen Sie zuerst, ob das Token noch gültig war.

Vollständiges Codebeispiel

Alle Schritte zusammengefügt zu einem lauffähigen Skript mit sauberem Aufräumen im finally-Block:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
import time

API_KEY = "YOUR_API_KEY"

def solve_recaptcha_v2(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
    })
    if not resp.text.startswith("OK|"):
        raise Exception(f"Submit failed: {resp.text}")
    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 result.text.startswith("OK|"):
            return result.text.split("|")[1]
        raise Exception(f"Solve failed: {result.text}")
    raise TimeoutError("Timed out")

def main():
    options = Options()
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver = webdriver.Chrome(options=options)

    try:
        driver.get("https://example.com/login")
        wait = WebDriverWait(driver, 10)

        # Extract site key
        recaptcha = wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, "g-recaptcha"))
        )
        site_key = recaptcha.get_attribute("data-sitekey")

        # Solve
        token = solve_recaptcha_v2(site_key, driver.current_url)

        # Inject and submit
        driver.execute_script(
            f"document.getElementById('g-recaptcha-response').innerHTML = '{token}';"
        )
        driver.find_element(By.CSS_SELECTOR, "form").submit()

        wait.until(EC.url_changes(driver.current_url))
        print("Login successful!")

    finally:
        driver.quit()

if __name__ == "__main__":
    main()

Weitere CAPTCHA-Typen: reCAPTCHA v3 und Turnstile

Der Aufbau bleibt identisch – es ändern sich nur der method-Parameter und ein paar Zusatzfelder. Für reCAPTCHA v3 kommen version und action hinzu, da v3 einen Score anhand der Aktion vergibt:

def solve_recaptcha_v3(site_key, page_url, action="verify"):
    resp = requests.get("https://ocr.captchaai.com/in.php", params={
        "key": API_KEY,
        "method": "userrecaptcha",
        "googlekey": site_key,
        "pageurl": page_url,
        "version": "v3",
        "action": action
    })
    task_id = resp.text.split("|")[1]
    # ... same polling logic

Cloudflare Turnstile nutzt die Methode turnstile und den Parameter sitekey. In der Praxis ist Turnstile eher schnell gelöst – laut CaptchaAI typischerweise in unter 10 Sekunden:

def solve_turnstile(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
    })
    task_id = resp.text.split("|")[1]
    # ... same polling logic

Hinweis: Die genannten Lösungszeiten sind Richtwerte von CaptchaAI und hängen von CAPTCHA-Typ, Region und Auslastung ab. Für kritische Workflows sollten eigene Messungen die Grundlage bilden.

CaptchaAI löst darüber hinaus reCAPTCHA v2 Invisible und Enterprise, GeeTest v3, Cloudflare Challenge sowie Bild- und Raster-CAPTCHAs – der gezeigte Solver lässt sich für jeden dieser Typen wiederverwenden, indem Sie Methode und Parameter anpassen.

Selenium-Scraper produktiv betreiben (DACH-Kontext)

Ein Skript auf dem Laptop ist der Anfang; im Dauerbetrieb läuft es meist auf einem eigenen Server. Ein typisches Setup im DACH-Raum ist ein Headless-Chrome auf einem Hetzner- oder netcup-VPS, angestoßen über GitLab CI oder GitHub Actions in festen Intervallen. Weil CaptchaAI das Lösen serverseitig erledigt, brauchen diese Worker keine Grafikoberfläche – der Browser lädt nur die Seite und liefert den Sitekey.

Zwei Punkte lohnen sich vorab:

  • Threads statt Solves einplanen. CaptchaAI rechnet pro gleichzeitigem Thread ab, nicht pro Lösung. Ein BASIC-Plan (15 $/Monat, 5 Threads) deckt fünf parallele CAPTCHAs ab; skalieren mehrere Worker gleichzeitig, greifen STANDARD (30 $/Monat, 15 Threads) oder ADVANCE (90 $/Monat, 50 Threads). Preise in US-Dollar.
  • DSGVO im Blick behalten. Beim Scraping fallen häufig IP-Adressen und weitere personenbezogene Daten an. Prüfen Sie Rechtsgrundlage und Datenflüsse selbst – das ist Sorgfaltspflicht auf Ihrer Seite, keine Aussage über CaptchaAI.

Für DACH-Anwendungsfälle wie BLS-Terminportale liefert CaptchaAI einen eigenen BLS-Solver; das Grundmuster – Parameter auslesen, an die API geben, Token einsetzen – bleibt dasselbe.

Fehlerbehebung

Problem Ursache Lösung
Token abgelehnt Das Token ist vor der Übermittlung abgelaufen Innerhalb von 120 Sekunden einfügen und absenden
Sitekey nicht gefunden CAPTCHA wird dynamisch nachgeladen WebDriverWait mit längerem Timeout einsetzen
NoSuchElementException Falscher Selektor Seite inspizieren und das richtige Element ermitteln
ChromeDriver-Version passt nicht Chrome wurde aktualisiert Passende ChromeDriver-Version herunterladen
Blockade trotz korrektem Token Anti-Bot-Schutz über das CAPTCHA hinaus undetected-chromedriver einsetzen und Browser-Flags prüfen

FAQ

Wie viele CAPTCHAs kann ich parallel lösen?

So viele, wie Ihr Plan Threads hat. Ein Thread ist ein gerade laufendes CAPTCHA; sobald eine Lösung fertig ist, nimmt der Thread das nächste. BASIC bietet 5 Threads, ADVANCE 50 – die Lösungen pro Thread sind unbegrenzt.

Welcher CaptchaAI-Plan passt zu einem Selenium-Scraper?

Das hängt von der gewünschten Parallelität ab, nicht vom Volumen. Für einen einzelnen Worker reicht BASIC (15 $/Monat, 5 Threads). Laufen mehrere Scraper gleichzeitig, planen Sie einen Thread pro erwartetem gleichzeitigem CAPTCHA ein.

Warum wird mein Token trotz korrekter Lösung abgelehnt?

Meist ist es abgelaufen. reCAPTCHA-Tokens sind rund 120 Sekunden gültig – lösen Sie das CAPTCHA erst kurz vor dem Absenden und fügen Sie es direkt vor der Formularübermittlung ein, statt es zwischenzuspeichern.

Brauche ich undetected-chromedriver zusätzlich zu CaptchaAI?

Nur, wenn die Seite über das CAPTCHA hinaus auf Automatisierung prüft. CaptchaAI liefert ein gültiges Token; blockiert die Seite trotzdem, liegt es am Browser-Fingerprint, nicht am Token. Dann helfen undetected-chromedriver und angepasste Browser-Flags.

Was ist mit reCAPTCHA, das Callbacks nutzt?

Manche Seiten rufen eine JavaScript-Callback-Funktion auf, statt das Formular klassisch abzusenden. Lösen Sie den Callback dann per driver.execute_script() mit dem gelösten Token aus – Details unter reCAPTCHA-v2-Callback per API lösen.

Verwandte Leitfäden

Kommentare sind für diesen Artikel deaktiviert.