Tutorials

Extrahieren von reCAPTCHA-Parametern aus der Seitenquelle

Der reCAPTCHA-Sitekey steht in nahezu jedem Fall im Klartext im HTML einer Seite – Sie müssen ihn nur an der richtigen Stelle auslesen. Genau dieser Wert entscheidet darüber, ob ein Solve über CaptchaAI beim ersten Aufruf funktioniert oder mit einem falschen Parameter ins Leere läuft. Neben dem Sitekey verlangen manche reCAPTCHA-Varianten weitere Angaben: die action bei v3, den data-s-Wert bei Google-eigenen Seiten und das Enterprise-Kennzeichen bei reCAPTCHA Enterprise.

Dieser Leitfaden zeigt, wo jeder dieser Werte tatsächlich liegt und wie Sie ihn zuverlässig extrahieren – von der rein statischen HTML-Analyse bis zum vollständig gerenderten DOM. Alle Beispiele sind so aufgebaut, dass Sie die extrahierten Parameter direkt an die CaptchaAI-API weiterreichen können.


Welche Parameter reCAPTCHA je Version verlangt

Bevor Sie extrahieren, sollten Sie wissen, welche Felder die jeweilige reCAPTCHA-Variante überhaupt benötigt. googlekey und pageurl sind immer Pflicht; alles andere hängt vom Typ ab.

Parameter v2 Standard v2 Invisible v3 Enterprise
googlekey (Sitekey) Erforderlich Erforderlich Erforderlich Erforderlich
pageurl Erforderlich Erforderlich Erforderlich Erforderlich
invisible 1
action Erforderlich Manchmal
data-s Manchmal Manchmal
enterprise 1

Der häufigste Grund für einen abgelehnten Solve ist nicht ein falscher Sitekey, sondern ein fehlender Zusatzparameter: ein v3-Sitekey ohne passende action oder eine Enterprise-Instanz ohne gesetztes enterprise-Flag. Prüfen Sie die Tabelle also, bevor Sie an der Extraktion zweifeln.


Welche Methode passt zu welcher Seite?

Vier Muster decken praktisch jede reCAPTCHA-Einbindung ab. Als Orientierung, bevor Sie in den Code einsteigen:

  • Statisches HTML mit sichtbarem Widget: Regex auf data-sitekey (Methode 1) – am schnellsten, kein Browser nötig.
  • reCAPTCHA v3 oder Enterprise: Sitekey aus der Skript-URL, action aus dem grecaptcha.execute-Aufruf (Methode 2).
  • Widget in einem Iframe gekapselt: Sitekey aus dem k-Parameter der Anchor-URL (Methode 3).
  • Rein per JavaScript aufgebaut: Konfiguration aus grecaptcha.render() lesen oder das gerenderte DOM auswerten (Methode 4).

Methode 1: Parameter aus HTML-Attributen lesen

Bei klassischem reCAPTCHA v2 rendert die Seite ein <div class="g-recaptcha"> mit data--Attributen. Für statisch ausgelieferte Seiten genügt ein einzelner HTTP-Request und ein paar Regex-Abfragen – kein Browser nötig.

Sitekey aus dem data-sitekey-Attribut

import re
import requests

url = "https://example.com/login"
html = requests.get(url).text

# Find data-sitekey
match = re.search(r'data-sitekey=["\']([A-Za-z0-9_-]+)["\']', html)
if match:
    sitekey = match.group(1)
    print(f"Sitekey: {sitekey}")

# Check if invisible
invisible_match = re.search(r'data-size=["\']invisible["\']', html)
is_invisible = bool(invisible_match)
print(f"Invisible: {is_invisible}")

# Find callback
callback_match = re.search(r'data-callback=["\'](\w+)["\']', html)
callback = callback_match.group(1) if callback_match else None
print(f"Callback: {callback}")

# Check for data-s (Google-owned sites)
data_s_match = re.search(r'data-s=["\']([^"\']+)["\']', html)
data_s = data_s_match.group(1) if data_s_match else None
print(f"data-s: {data_s}")

Aus denselben Attributen lesen Sie nebenbei die Größe (data-size) und einen eventuellen data-callback-Handler mit aus – beides hilft später bei der Fehlersuche.

Dasselbe im gerenderten DOM mit Puppeteer

Liefert der Server nur ein leeres Grundgerüst und baut JavaScript das Widget erst nach, greift die Regex-Variante ins Leere. Dann lesen Sie die Attribute im fertig gerenderten DOM aus:

const puppeteer = require('puppeteer');

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/login', { waitUntil: 'networkidle2' });

const params = await page.evaluate(() => {
  const widget = document.querySelector('.g-recaptcha');
  if (!widget) return null;

  return {
    sitekey: widget.getAttribute('data-sitekey'),
    size: widget.getAttribute('data-size'),
    callback: widget.getAttribute('data-callback'),
    dataS: widget.getAttribute('data-s'),
    invisible: widget.getAttribute('data-size') === 'invisible',
  };
});

console.log(params);

Methode 2: Sitekey und action aus Skript-Tags

reCAPTCHA v3 und Enterprise binden ihren Sitekey nicht in ein sichtbares Widget ein, sondern in die Skript-URL. Der Wert steht im render-Parameter der geladenen api.js beziehungsweise enterprise.js.

v3- und Enterprise-Sitekeys erkennen

# Find sitekey from script src
v3_match = re.search(
    r'recaptcha/(?:api|enterprise)\.js\?.*?render=([A-Za-z0-9_-]+)',
    html
)
if v3_match:
    sitekey = v3_match.group(1)
    print(f"v3 Sitekey: {sitekey}")

# Check enterprise
is_enterprise = 'enterprise.js' in html
print(f"Enterprise: {is_enterprise}")

Taucht enterprise.js im Quelltext auf, handelt es sich um eine Enterprise-Instanz – dann muss enterprise=1 mit übermittelt werden.

Die action aufspüren

Die action steht bei v3 nie in einem HTML-Attribut, sondern wird im JavaScript an grecaptcha.execute übergeben. Sie suchen also den Aufruf selbst:

# Search for grecaptcha.execute calls
action_match = re.search(
    r'grecaptcha\.execute\s*\([^,]+,\s*\{[^}]*action\s*:\s*["\']([^"\']+)',
    html
)
if action_match:
    action = action_match.group(1)
    print(f"Action: {action}")

Methode 3: Sitekey aus dem Iframe-src

Manche Seiten kapseln das Widget in einem Iframe. Dann steckt der Sitekey im k-Parameter der Anchor-URL des Iframes:

# Find reCAPTCHA iframe
iframe_match = re.search(
    r'<iframe[^>]+src=["\']([^"\']*recaptcha/api2/anchor[^"\']*)["\']',
    html
)
if iframe_match:
    iframe_src = iframe_match.group(1)
    sitekey_match = re.search(r'k=([A-Za-z0-9_-]+)', iframe_src)
    if sitekey_match:
        sitekey = sitekey_match.group(1)
        print(f"Iframe sitekey: {sitekey}")

Diese Variante ist der Rettungsanker, wenn weder ein data-sitekey-Attribut noch ein render-Parameter zu finden ist, das Widget aber sichtbar geladen wird.


Methode 4: Dynamisch gerendertes reCAPTCHA

Seiten, die das Widget programmatisch mit grecaptcha.render() erzeugen, tragen den Sitekey im übergebenen Konfigurationsobjekt. Sie lesen ihn direkt aus dem Funktionsaufruf:

# Find grecaptcha.render calls
render_match = re.search(
    r'grecaptcha\.render\s*\([^,]*,\s*\{([^}]+)\}',
    html
)
if render_match:
    config = render_match.group(1)
    sk = re.search(r'sitekey\s*:\s*["\']([A-Za-z0-9_-]+)', config)
    cb = re.search(r'callback\s*:\s*["\']?(\w+)', config)
    sz = re.search(r'size\s*:\s*["\'](\w+)', config)
    print(f"Sitekey: {sk.group(1) if sk else 'not found'}")
    print(f"Callback: {cb.group(1) if cb else 'not found'}")
    print(f"Size: {sz.group(1) if sz else 'not found'}")

Alle Methoden in einer Funktion bündeln

Im Produktivbetrieb wissen Sie vorab selten, welches Muster eine Seite verwendet. Sinnvoll ist deshalb eine Funktion, die alle vier Wege der Reihe nach durchprobiert und den erstbesten Treffer nimmt:

import re
import requests

def extract_recaptcha_params(url):
    html = requests.get(url, timeout=15).text
    params = {"pageurl": url}

    # Sitekey from data-sitekey
    sk = re.search(r'data-sitekey=["\']([A-Za-z0-9_-]+)', html)
    if sk:
        params["sitekey"] = sk.group(1)

    # Sitekey from script render parameter (v3)
    if "sitekey" not in params:
        v3 = re.search(r'render=([A-Za-z0-9_-]{20,})', html)
        if v3:
            params["sitekey"] = v3.group(1)

    # Sitekey from iframe
    if "sitekey" not in params:
        iframe = re.search(r'recaptcha.*?k=([A-Za-z0-9_-]+)', html)
        if iframe:
            params["sitekey"] = iframe.group(1)

    # Sitekey from grecaptcha.render
    if "sitekey" not in params:
        render = re.search(r'sitekey\s*:\s*["\']([A-Za-z0-9_-]+)', html)
        if render:
            params["sitekey"] = render.group(1)

    # Version detection
    if re.search(r'data-size=["\']invisible', html):
        params["invisible"] = True
    if 'enterprise.js' in html:
        params["enterprise"] = True

    # Action (v3)
    action = re.search(
        r'action\s*:\s*["\']([^"\']+)',
        html[html.find('grecaptcha.execute'):] if 'grecaptcha.execute' in html else ''
    )
    if action:
        params["action"] = action.group(1)

    # data-s
    ds = re.search(r'data-s=["\']([^"\']+)', html)
    if ds:
        params["data_s"] = ds.group(1)

    # Callback
    cb = re.search(r'data-callback=["\'](\w+)', html)
    if cb:
        params["callback"] = cb.group(1)

    return params

# Usage
params = extract_recaptcha_params("https://example.com/login")
for k, v in params.items():
    print(f"  {k}: {v}")

Die Reihenfolge ist bewusst gewählt: Das eindeutige data-sitekey-Attribut hat Vorrang, die unschärferen Muster greifen erst, wenn nichts anderes passt. So vermeiden Sie, dass ein Iframe-Treffer den korrekten v2-Sitekey überschreibt.

Eine typische Ausgabe sieht so aus:

  pageurl: https://example.com/login
  sitekey: 6Le-SITEKEY-abc123
  invisible: True
  callback: onCaptchaComplete

Extrahierte Parameter an CaptchaAI übermitteln

Stehen die Werte fest, bauen Sie daraus die Anfrage an den Endpunkt in.php. Optionale Felder setzen Sie nur, wenn die Extraktion sie tatsächlich geliefert hat:

data = {
    "key": API_KEY,
    "method": "userrecaptcha",
    "googlekey": params["sitekey"],
    "pageurl": params["pageurl"],
    "json": "1",
}

if params.get("invisible"):
    data["invisible"] = "1"
if params.get("enterprise"):
    data["enterprise"] = "1"
if params.get("action"):
    data["action"] = params["action"]
if params.get("data_s"):
    data["data-s"] = params["data_s"]

resp = requests.post("https://ocr.captchaai.com/in.php", data=data).json()

Alle sechs reCAPTCHA-Varianten laufen über dieselbe method-Kennung userrecaptcha; den Unterschied machen allein die Zusatzfelder. Die Abrechnung erfolgt bei CaptchaAI Thread-basiert – jeder Plan von BASIC (15 $/Monat, 5 Threads) bis VIP-3 (7.500 $/Monat, 5.000 Threads) enthält unbegrenzte Lösungen pro Thread.


Praxisbeispiel: Extraktion im laufenden Scraping-Betrieb

Angenommen, ein Team betreibt auf einem Hetzner-Server eine Reihe von Worker-Prozessen, die täglich Formularseiten eines eigenen oder ausdrücklich freigegebenen Portals abfragen. Statt den Sitekey einmalig fest zu verdrahten, ruft jeder Worker vor dem Solve extract_recaptcha_params() auf. Dadurch fällt sofort auf, wenn der Betreiber die Seite von reCAPTCHA v2 auf v3 umstellt oder eine Enterprise-Instanz einführt – der Worker liest dann automatisch die action beziehungsweise das enterprise-Flag mit, ohne dass jemand Code anpassen muss.

Wer im DACH-Raum scrapt, sollte zusätzlich die datenschutzrechtliche Seite im Blick behalten: IP-Adressen gelten nach DSGVO als personenbezogene Daten. Prüfen Sie Rechtsgrundlage und Datenfluss Ihrer Extraktion – das ist Sorgfaltspflicht des Betreibers, keine Eigenschaft des Solvers.


Häufige Fehler bei der Extraktion

Problem Ursache Lösung
Kein Sitekey gefunden Die Seite rendert das Widget dynamisch Puppeteer oder Selenium statt statischem HTML verwenden
Falscher Sitekey Mehrere reCAPTCHA-Instanzen auf einer Seite Prüfen, welches Widget zu dem von Ihnen abgesendeten Formular gehört
action nicht gefunden In einer externen JS-Datei definiert Verlinkte JavaScript-Dateien nachladen und durchsuchen
data-s ändert sich pro Anfrage Google generiert den Wert neu Für jeden Solve ein frisches data-s extrahieren

FAQ

Woran erkenne ich, ob eine Seite reCAPTCHA v2 oder v3 verwendet?

An der geladenen Skript-URL. Ein data-sitekey-Attribut auf einem .g-recaptcha-Element deutet auf v2 hin; ein render-Parameter in der api.js sowie Aufrufe von grecaptcha.execute mit action sind das Kennzeichen von v3. Taucht enterprise.js auf, handelt es sich um die Enterprise-Variante.

Warum wird mein Solve trotz korrektem Sitekey abgelehnt?

Meist fehlt ein Zusatzparameter. Bei v3 muss die passende action mitgeschickt werden, bei Enterprise das Feld enterprise=1. Prüfen Sie außerdem, ob die pageurl exakt der Seite entspricht, auf der das CAPTCHA erscheint – schon ein abweichender Pfad kann den Solve scheitern lassen.

Muss ich den data-s-Wert für jede Anfrage neu extrahieren?

Ja, auf Google-eigenen Seiten. Google generiert data-s pro Anfrage neu, sodass ein zwischengespeicherter Wert schnell ungültig wird. Extrahieren Sie ihn deshalb unmittelbar vor jedem Solve frisch aus dem aktuellen Quelltext.

Ist der Sitekey dasselbe wie mein API-Schlüssel?

Nein. Der Sitekey ist ein öffentlicher Schlüssel der Website und steht bewusst sichtbar im Quelltext – seine Weitergabe ist unbedenklich. Ihr CaptchaAI-API-Schlüssel dagegen ist privat und gehört niemals in den Client-Code oder in ein öffentliches Repository.


reCAPTCHA-Parameter direkt mit CaptchaAI lösen

Sobald Sitekey, action und Enterprise-Kennzeichen sauber extrahiert sind, ist der eigentliche Solve nur noch ein API-Aufruf. Holen Sie sich Ihren API-Schlüssel unter captchaai.com und starten Sie mit dem Schnellstart-Guide.


Verwandte Leitfäden

Kommentare sind für diesen Artikel deaktiviert.