API-Tutorials

Benutzerdefinierte CAPTCHA-Typen: ungewöhnliche Abfragen an CaptchaAI übermitteln

Für ungewöhnliche CAPTCHA-Typen – ein Slider, ein Drehbild, eine Audiospur oder ein komplett eigenes JavaScript-Widget – gibt es bei CaptchaAI einen universellen Weg: Screenshot machen, als Base64 kodieren und eine präzise Textanweisung mitschicken. Über den Parameter textinstructions des OCR-Endpunkts sagen Sie dem Solver genau, welchen Wert er zurückgeben soll. Dieser Leitfaden zeigt, wie Sie Slider-, Rotations-, Reihenfolge-, Audio- und Widget-CAPTCHAs mit Python und Selenium an in.php/res.php übermitteln – und wie Sie den passenden Typ vorab automatisch erkennen, statt für jede Seite eine eigene Logik zu pflegen.

Bild plus Textanweisung: die universelle Methode

Die Grundlage für alle Sonderfälle ist eine einzige Funktion. Sie schickt das Base64-Bild zusammen mit einer Klartext-Anweisung an in.php, fragt danach res.php ab, bis ein Ergebnis vorliegt, und gibt den gelösten Wert zurück. method ist dabei base64, das Bild steht im Feld body:

import requests
import base64
import time
import os

API_KEY = os.environ["CAPTCHAAI_API_KEY"]


def solve_custom_captcha(image_b64, instructions):
    """Solve any visual CAPTCHA using image + text instructions."""
    resp = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": API_KEY,
        "method": "base64",
        "body": image_b64,
        "textinstructions": instructions,
        "json": 1,
    }, timeout=30)

    result = resp.json()
    if result.get("status") != 1:
        raise RuntimeError(result.get("request"))

    task_id = result["request"]

    time.sleep(10)
    for _ in range(30):
        resp = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": API_KEY, "action": "get",
            "id": task_id, "json": 1,
        }, timeout=15)
        data = resp.json()
        if data.get("status") == 1:
            return data["request"]
        if data["request"] != "CAPCHA_NOT_READY":
            raise RuntimeError(data["request"])
        time.sleep(5)

    raise TimeoutError("Solve timeout")

Drei Parameter entscheiden über das Ergebnis:

  • body – das Base64-Bild.
  • textinstructions – die Klartext-Anweisung an den Solver.
  • json: 1 – erzwingt eine strukturierte JSON-Antwort.

Formulieren Sie die Anweisung so eng wie möglich: „Nur die X-Koordinate als Zahl zurückgeben" liefert verwertbaren Code, „Beschreibe das Bild" dagegen Fließtext, den Sie nicht weiterverarbeiten können.

Ungewöhnliche CAPTCHA-Typen im Überblick

Fast jedes „exotische" CAPTCHA lässt sich auf eine Handvoll Interaktionsmuster zurückführen. Die folgende Übersicht ordnet jedem Muster den passenden Lösungsansatz zu:

Typ Merkmale Ansatz
Slider-CAPTCHA Regler an die Zielposition ziehen Screenshot als Bild, Textanweisung nutzen
Puzzle (Jigsaw) Puzzleteil passend einsetzen kann einem GeeTest-v3-Ansatz zugeordnet werden
Audio-CAPTCHA anhören und eintippen Audiodatei übermitteln
Bild drehen in die korrekte Ausrichtung rotieren Screenshot + Anweisung
Reihenfolge wählen Elemente nacheinander anklicken Rasterbild-Ansatz verwenden
Rechenaufgabe Arithmetik lösen Parameter calc=1 verwenden
Interaktives Custom-Widget sitespezifisches JS-Widget Screenshot + Textanweisung

Sobald sich eine Abfrage als Bild darstellen lässt, wird sie lösbar. Die eigentliche Arbeit steckt in der Formulierung der Anweisung, nicht im Transportweg.

Slider-CAPTCHAs: die Zielposition bestimmen

Ein Slider verlangt, einen Regler bis zu einer bestimmten Stelle zu ziehen. Sie fotografieren das Widget, lassen sich von der API die X-Verschiebung als Zahl geben und führen den Zug anschließend mit Selenium ActionChains aus:

# slider_captcha.py
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains


def solve_slider_captcha(driver, captcha_selector):
    """Screenshot slider CAPTCHA and solve via CaptchaAI."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "What pixel position should the slider be dragged to? "
        "Return only the X offset number."
    )

    try:
        offset = int(result)
    except ValueError:
        return False

    # Drag slider to position
    slider = driver.find_element(By.CSS_SELECTOR, ".slider-handle")
    ActionChains(driver).click_and_hold(slider).move_by_offset(offset, 0).release().perform()

    return True

Der zurückgegebene Offset ist ein Pixelwert. Prüfen Sie ihn mit int() ab, bevor Sie ihn an move_by_offset übergeben – so fängt Ihre Integration eine unerwartete Textantwort sauber ab.

Rotations-CAPTCHAs: den Drehwinkel ermitteln

Bei Drehbildern muss ein Motiv in die aufrechte Lage rotiert werden. Statt nach Pixeln fragen Sie hier nach Grad im Uhrzeigersinn und rechnen daraus die Klicks aus – die meisten Widgets rotieren pro Klick um 90 Grad:

# rotation_captcha.py


def solve_rotation_captcha(driver, captcha_selector):
    """Solve rotation CAPTCHA."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "How many degrees should this image be rotated clockwise "
        "to be in the correct upright orientation? Return only the number."
    )

    try:
        degrees = int(result)
    except ValueError:
        return False

    # Click rotation button the correct number of times
    rotate_btn = driver.find_element(By.CSS_SELECTOR, ".rotate-button")
    clicks = degrees // 90  # Each click rotates 90 degrees

    for _ in range(clicks):
        rotate_btn.click()
        time.sleep(0.3)

    return True

Der Ausdruck degrees // 90 übersetzt den Winkel in die Zahl der Klicks. Fordern Sie in der Anweisung ausschließlich eine Zahl an, damit die Division verlässlich funktioniert.

Reihenfolge-CAPTCHAs: Elemente in der richtigen Sequenz anklicken

Manche Abfragen verlangen, Objekte in einer definierten Reihenfolge anzuklicken – etwa Zahlen aufsteigend oder Symbole nach einer Vorgabe. Sie lassen sich die Reihenfolge als kommaseparierte Positionsliste zurückgeben und klicken die Elemente entsprechend an:

# order_captcha.py


def solve_order_captcha(driver, captcha_selector, item_selector):
    """Solve click-in-order CAPTCHA."""
    captcha = driver.find_element(By.CSS_SELECTOR, captcha_selector)
    image_b64 = captcha.screenshot_as_base64

    result = solve_custom_captcha(
        image_b64,
        "What is the correct order? Return as comma-separated "
        "numbers (1-indexed) representing positions left-to-right, top-to-bottom."
    )

    # Parse order
    try:
        order = [int(x.strip()) for x in result.split(",")]
    except ValueError:
        return False

    # Click items in order
    items = driver.find_elements(By.CSS_SELECTOR, item_selector)
    for idx in order:
        if 1 <= idx <= len(items):
            items[idx - 1].click()
            time.sleep(0.5)

    return True

Die 1-basierten Positionen beziehen sich auf die Lesereihenfolge von links nach rechts und oben nach unten. Die Bereichsprüfung 1 <= idx <= len(items) verhindert Klicks auf nicht vorhandene Elemente.

Audio-CAPTCHAs als barrierefreie Alternative

Viele Portale bieten neben dem Bild eine Audiovariante an. Sie laden die Audiodatei herunter, kodieren sie als Base64 und übermitteln sie mit einer Transkriptionsanweisung über denselben Weg wie ein Bild:

# audio_captcha.py
import requests


def solve_audio_captcha(audio_url):
    """Download and solve an audio CAPTCHA."""
    # Download audio
    resp = requests.get(audio_url, timeout=30)
    audio_b64 = base64.b64encode(resp.content).decode("ascii")

    # Submit as image with instructions
    # CaptchaAI may support audio via the base64 method
    result = solve_custom_captcha(
        audio_b64,
        "This is an audio CAPTCHA. Transcribe the spoken characters."
    )
    return result

Ob eine Audiospur verarbeitet werden kann, hängt von Format und Länge ab. Testen Sie mit einer echten Datei aus dem Zielportal, bevor Sie diesen Pfad produktiv nutzen.

Vollständig benutzerdefinierte Widgets verarbeiten

Für sitespezifische Widgets ohne bekanntes Muster kombinieren Sie alle Schritte: Screenshot des gesamten Widgets, Auslesen der sichtbaren Anweisung aus dem DOM, Übermittlung an den Solver und Eintragen des Ergebnisses – entweder in ein Eingabefeld oder per JavaScript:

# custom_widget.py
from selenium import webdriver
from selenium.webdriver.common.by import By


def handle_custom_widget(driver, widget_selector):
    """Handle an unknown custom CAPTCHA widget."""

    # Step 1: Screenshot the entire widget
    widget = driver.find_element(By.CSS_SELECTOR, widget_selector)
    image_b64 = widget.screenshot_as_base64

    # Step 2: Get any visible instructions
    try:
        instructions_el = widget.find_element(By.CSS_SELECTOR, ".instructions, .prompt, p")
        visible_instructions = instructions_el.text
    except Exception:
        visible_instructions = "Solve this CAPTCHA"

    # Step 3: Submit with descriptive instructions
    result = solve_custom_captcha(
        image_b64,
        f"CAPTCHA instructions: {visible_instructions}. "
        f"Return the answer text."
    )

    # Step 4: Try to submit result
    try:
        input_el = widget.find_element(By.CSS_SELECTOR, "input")
        input_el.clear()
        input_el.send_keys(result)
    except Exception:
        # No input — try clicking based on result
        driver.execute_script("""
            var input = document.querySelector('input[name*="captcha"]');
            if (input) input.value = arguments[0];
        """, result)

    return result

Der Fallback per execute_script greift, wenn kein sichtbares input-Feld existiert. Lesen Sie die sichtbare Anweisung direkt aus dem Widget aus – so bleibt die Funktion auch bei geändertem Markup robust.

CAPTCHA-Typ automatisch erkennen und routen

Statt für jede Seite manuell den Typ festzulegen, erkennen Sie ihn anhand des Seiten-HTML. Der folgende Detektor prüft auf typische Signaturen – von reCAPTCHA über Turnstile und GeeTest bis zu BLS – und liefert eine Liste der erkannten Typen zurück:

# detector.py
import re


def detect_captcha_type(page_html):
    """Detect which CAPTCHA type is on a page."""
    checks = {
        "recaptcha_v2": r'data-sitekey.*g-recaptcha',
        "recaptcha_v3": r'recaptcha/api\.js\?render=',
        "turnstile": r'cf-turnstile|challenges\.cloudflare\.com/turnstile',
        "geetest": r'gt\b.*challenge|geetest',
        "bls": r'method.*bls|bls-captcha',
        "image_text": r'captcha.*\.(png|jpg|gif|jpeg)',
        "slider": r'slider.*captcha|slide.*verify',
        "audio": r'audio.*captcha|captcha.*audio',
    }

    detected = []
    for captcha_type, pattern in checks.items():
        if re.search(pattern, page_html, re.IGNORECASE):
            detected.append(captcha_type)

    return detected if detected else ["unknown"]

Verdrahten Sie das Ergebnis mit einem Dispatcher, der reCAPTCHA v2/v3, Turnstile und GeeTest v3 an die jeweiligen Standardmethoden weiterreicht und nur die verbleibenden Sonderfälle über die Bild-plus-Anweisung-Route schickt.

Praxis im DACH-Raum: Terminportale, Recht und Betrieb

Ein häufiger Anwendungsfall in Deutschland, Österreich und der Schweiz sind BLS- und Visa-Terminportale: Sie kombinieren Bild- und Slider-Abfragen und lassen sich mit den hier gezeigten Mustern für eigene, legitime Terminbuchungen automatisieren. BLS-CAPTCHAs löst CaptchaAI über die native bls-Methode; für die exotischen Randfälle greift die universelle Bild-plus-Anweisung-Route.

Zwei Punkte gehören in jede Umsetzung:

  1. Rechtsgrundlage – prüfen Sie Nutzungsbedingungen und rechtliche Basis, bevor Sie automatisiert zugreifen.
  2. Betrieb – Selenium-Worker laufen zuverlässig auf einer Hetzner- oder netcup-VPS; eine GitLab-CI-Pipeline testet die Solver-Logik nach jeder Änderung gegen ein Test-Widget.

Hinweis: IP-Adressen gelten unter der DSGVO als personenbezogene Daten. Verifizieren Sie bei jedem Scraping-Projekt Ihre Datenflüsse und die Rechtsgrundlage – das ist Sorgfaltspflicht des Betreibers, keine Compliance-Zusage von CaptchaAI.

Fehlerbehebung

Problem Ursache Lösung
ERROR_CAPTCHA_UNSOLVABLE Bild unklar oder Anweisung zu vage Screenshot-Qualität und Anweisung verbessern
Falsches Antwortformat Solver liefert eine Beschreibung statt eines Werts präzise sein: „Nur die Zahl zurückgeben"
Widget nicht erfasst Element außerhalb des Viewports vor dem Screenshot zum Element scrollen
Interaktion schlägt fehl falsche Klickkoordinaten Lösung sorgfältig auf reale UI-Elemente abbilden

Häufige Fragen

Welche Parameter braucht ein benutzerdefiniertes Bild-CAPTCHA?

Vier: method auf base64, das Bild als Base64-String im Feld body, die textinstructions mit der konkreten Aufgabe und json: 1 für eine strukturierte Antwort. Übermittelt wird an in.php, das Ergebnis holen Sie von res.php ab.

Wie formuliere ich die Textanweisung, damit der Solver einen verwertbaren Wert liefert?

Geben Sie das Ausgabeformat explizit vor. „Nur die X-Koordinate als Zahl zurückgeben" oder „Antwort als kommaseparierte Positionen" führen zu maschinenlesbaren Ergebnissen. Vage Anweisungen wie „Löse dieses CAPTCHA" liefern oft beschreibenden Text, den Sie nicht weiterverarbeiten können.

Was kostet das Lösen ungewöhnlicher CAPTCHA-Typen?

CaptchaAI rechnet pro Thread ab, nicht pro Lösung – es gibt keinen Aufpreis nach CAPTCHA-Typ. Der Einstieg ist BASIC ab 15 $/Monat mit 5 Threads und unbegrenzten Lösungen pro Thread; höhere Tarife wie ADVANCE (90 $/Monat, 50 Threads) skalieren die Parallelität. Preise in US-Dollar.

Löst CaptchaAI auch GeeTest v4 oder hCaptcha?

hCaptcha und FunCaptcha werden derzeit nicht unterstützt. GeeTest v4 ist als „bald verfügbar" angekündigt, aber noch nicht verfügbar; GeeTest v3 lösen Sie dagegen über die native geetest-Methode.

Verwandte Leitfäden

  • Strategien für mehrzeichige Bild-CAPTCHAs
  • Best Practices für die Base64-Kodierung von Bildern

Ungewöhnliche CAPTCHA-Typen automatisch verarbeiten – jetzt mit CaptchaAI starten.

Kommentare sind für diesen Artikel deaktiviert.