So lösen Sie reCAPTCHA mit dem data-s-Parameter in Python

recaptcha data-s parameter - How to Solve reCAPTCHA with the data-s Parameter in Python

Auf Googles eigenen Seiten liefert das reCAPTCHA-Widget einen zusätzlichen Wert mit, und der heißt data-s. Lösen Sie ein solches Captcha auf die übliche Weise, bekommen Sie ein Token zurück, das die Seite anschließend ablehnt. Die Abhilfe ist ein weiteres Argument: Lesen Sie data-s aus dem Seiten-HTML, übergeben Sie es an den Solver und senden Sie das Token sofort ab.

Der data-s-Parameter von reCAPTCHA ist das Detail, das fast alle übersehen, vor allem weil es ihn auf normalen Seiten gar nicht gibt. Hier steht, wo er sitzt, wie er heißt und wie ein Skript aussieht, das von Anfang bis Ende funktioniert.

Was data-s wirklich ist

Es ist ein kurzlebiger, nur einmal verwendbarer Wert, den Google auf seinen eigenen Websites an reCAPTCHA-Widgets anhängt. Am häufigsten begegnet Ihnen die “unusual traffic”-Zwischenseite in der Google-Suche. Der Wert bindet die Challenge an genau diesen Seitenaufruf, sodass das zurückgegebene Token nur im selben Anfragekontext gültig ist.

Daraus folgen drei Dinge, und alle drei führen zu Fehlern:

  • Er läuft ab. Behandeln Sie ihn wie eine Nonce. Seite abrufen, lösen, absenden. Cachen Sie ihn nicht zwischen zwei Läufen.
  • Er existiert nur bei Google. Ein reCAPTCHA auf einer fremden Website hat kein data-s. Es trotzdem zu senden ist ein Parameterfehler und kein harmloser Zusatz.
  • Er ist nicht das Enterprise-Flag. Beide werden ständig verwechselt. data-s und enterprise sind getrennte Optionen, die unterschiedliche Probleme lösen, und die reCAPTCHA-Enterprise-Löser -Seite behandelt die zweite Option.

Was Sie brauchen

  • CapSkip läuft lokal. Standardmäßig lauscht es auf 127.0.0.1:8080 und die Einrichtungsanleitung -Seite erklärt die Installation.
  • Python 3.10 oder neuer.
  • Das SDK und ein HTTP-Client.
# the CapSkip SDK plus requests for fetching the page
pip install capskip requests

Wo Sie den data-s-Wert finden

Beide Werte, die Sie brauchen, stehen am selben Element. Das Widget wird als div gerendert, mit data-sitekey und, nur auf Googles Seiten, data-s:

<div class="g-recaptcha"
     data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
     data-s="SGVsbG8gdGhlcmUsIHRoaXMgaXMgYSBvbmUtdGltZSB2YWx1ZQ">
</div>

Der Sitekey ist stabil und lässt sich fest im Code hinterlegen. Der data-s -Wert ändert sich bei jedem Laden, er muss also zur Laufzeit ausgelesen werden:

# pip install capskip requests
import re
import requests

PAGE = "https://www.google.com/search?q=example"

# Keep one session. The value is tied to the request that
# produced it, cookies included.
session = requests.Session()
html = session.get(PAGE, timeout=30).text

sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1)
datas   = re.search(r'data-s="([^"]+)"', html).group(1)

print(sitekey, datas)   # second value is single use

Kommt der zweite Treffer leer zurück, sind Sie nicht auf einer Google-Seite und brauchen diesen Parameter überhaupt nicht. Lösen Sie das Captcha dann als gewöhnliche v2-Challenge.

Übergeben Sie ihn als datas, nicht als data-s

Das ist die Namensfalle. Die rohe HTTP-API nimmt den Parameter genau so, wie er im HTML steht, data-s. Die SDKs können diesen Namen nicht verwenden, da ein Bindestrich in einem Python-Keyword-Argument nicht zulässig ist; deshalb heißt er in jedem SDK datas.

WoName
Seiten-HTMLdata-s
Rohe API auf in.phpdata-s
SDKs für Python, Node.js, PHP, .NETdatas

Damit geklärt, ist das Lösen ein einziger Aufruf:

from capskip import CapSkip

solver = CapSkip(host="127.0.0.1", port=8080)

result = solver.recaptcha(
    sitekey=sitekey,
    url=PAGE,
    datas=datas,      # the data-s value, scraped seconds ago
)

print(result["code"])   # g-recaptcha-response token

Vollständiges lauffähiges Beispiel

Abrufen, auslesen, lösen, absenden, alles in einer Session, damit Cookies und IP konsistent bleiben:

# pip install capskip requests
import re
import requests
from capskip import (
    CapSkip, ApiException, NetworkException, TimeoutException,
)

PAGE = "https://www.google.com/search?q=example"

session = requests.Session()
solver = CapSkip(host="127.0.0.1", port=8080, recaptchaTimeout=300)

html = session.get(PAGE, timeout=30).text
sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1)
datas   = re.search(r'data-s="([^"]+)"', html).group(1)

try:
    result = solver.recaptcha(sitekey=sitekey, url=PAGE, datas=datas)
except NetworkException:
    raise SystemExit("CapSkip is not running on 127.0.0.1:8080")
except TimeoutException:
    raise SystemExit("solve took longer than recaptchaTimeout")
except ApiException as err:
    raise SystemExit(f"API refused the task: {err}")

# Submit immediately. The token is good for about two minutes.
response = session.post(
    PAGE,
    data={"g-recaptcha-response": result["code"]},
    timeout=30,
)
print(response.status_code)

Zwei Details darin sind wichtiger, als sie aussehen. Die session wird wiederverwendet, sodass Lösung und Absenden dieselben Cookies teilen. Und das Absenden erfolgt direkt nach dem Lösen, denn ein reCAPTCHA-Token wird etwa zwei Minuten nach seiner Ausstellung nicht mehr akzeptiert.

Hinter einem Proxy

Wenn Sie die Seite über einen Proxy abgerufen haben, lösen Sie über denselben Proxy. Die Challenge ist an die Anfrage gebunden, die sie erzeugt hat, und eine Lösung über einen anderen Netzwerkpfad ist die zweithäufigste Ursache für ein abgelehntes Token.

result = solver.recaptcha(
    sitekey=sitekey,
    url=PAGE,
    datas=datas,
    proxy={"type": "HTTPS", "uri": "user:[email protected]:3128"},
)

Proxys funktionieren bei reCAPTCHA, Turnstile und GeeTest. Bei Bild-Captchas bringen sie nichts, denn diese erreichen die Zielseite nie.

Derselbe Aufruf ohne SDK

Die API ist 2captcha-kompatibel und läuft auf Ihrem Rechner, also genügt ein beliebiger HTTP-Client. Hier behält der Parameter seinen Bindestrich:

# submit the task, get an ID back
curl -s -X POST "http://127.0.0.1:8080/in.php" \
  -d "key=capskip" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://www.google.com/search?q=example" \
  -d "data-s=THE_DATA_S_VALUE" \
  -d "json=1"

# {"status":1,"request":"2122988149"}

Fragen Sie anschließend res.php wiederholt nach dem Token ab. Der vollständige Ablauf aus zwei Aufrufen, inklusive der Polling-Verzögerungen, steht in Captcha lösen mit cURL.

Andere SDKs verwenden dieselbe datas -Schreibweise. Node.js nimmt sie im Options-Objekt entgegen, und .NET legt sie ins Options-Dictionary:

// npm install capskip
const { CapSkip } = require('capskip');

const solver = new CapSkip({ host: '127.0.0.1', port: 8080 });

const result = await solver.recaptcha(sitekey, pageUrl, {
  datas: dataS,        // same value, same rules
});

console.log(result.code);

Häufige Fehler

Was Sie sehenUrsacheBeheben
ERROR_GOOGLEKEYDer Sitekey ist nie in die Anfrage gelangt, oder die Regex hat das falsche Attribut getroffenGeben Sie den ausgelesenen Wert vor dem Lösen aus. Details unter ERROR_GOOGLEKEY beheben
ERROR_BAD_PARAMETERSdata-s als leerer String gesendet oder an eine Nicht-Google-Seite geschicktÜbergeben Sie ihn nur, wenn das Attribut tatsächlich vorhanden ist
ERROR_CAPTCHA_UNSOLVABLEMeist ein veralteter data-s: Die Seite wurde Minuten vor dem Lösen abgerufenAbrufen und Lösen direkt hintereinander. Siehe ERROR_CAPTCHA_UNSOLVABLE
Token vom Solver akzeptiert, von Google abgelehntAndere Cookies oder eine andere IP zwischen Abruf und AbsendenVerwenden Sie eine Session wieder und für beides denselben Proxy
NetworkExceptionCapSkip läuft nichtStarten Sie die App und prüfen Sie den Port in den Einstellungen

Jeder Parameter und jedes Antwortformat ist aufgeführt in der API-Dokumentation.

Häufig gestellte Fragen

Brauche ich data-s auf einer normalen Website?

Nein. Er erscheint nur auf Googles eigenen Seiten. Wenn data-s nicht im HTML steht, lassen Sie das Argument ganz weg und lösen Sie das Captcha als Standard-v2-Challenge, so wie es die reCAPTCHA-v2-Löser -Seite beschreibt.

Ist data-s dasselbe wie das Enterprise-Flag?

Nein, und sie sind voneinander unabhängig. enterprise=1 sagt dem Solver, mit welchem reCAPTCHA-Produkt er es zu tun hat. datas überträgt einen einmaligen Wert von der Seite. Eine Challenge in der Google-Suche braucht den zweiten, und Sie können beide übergeben, wenn eine Seite das wirklich verlangt.

Wie lange bleibt der Wert gültig?

Rechnen Sie mit Sekunden, nicht mit Minuten. Er wird mit der Seite ausgegeben und stirbt mit ihr. Wenn Ihr Scraper Seiten in eine Warteschlange legt und sie später löst, rufen Sie die Seite zum Zeitpunkt des Lösens erneut ab, statt den Wert zu speichern.

Warum heißt es im Code datas, im HTML aber data-s?

Weil ein Bindestrich in einem Python-Keyword-Argument oder einem C#-Bezeichner nicht vorkommen darf. Die SDKs lassen ihn weg und senden den Namen mit Bindestrich für Sie über die Leitung. Der rohe in.php -Aufruf erwartet weiterhin data-s.

Zusammenfassung

Lesen Sie data-sitekey und data-s vom selben Element aus, übergeben Sie den zweiten Wert als datas, und senden Sie das Token in derselben Session innerhalb von ein paar Minuten ab. Lassen Sie eines dieser drei Dinge weg, bekommen Sie ein Token, das gut aussieht und trotzdem fehlschlägt.

Den restlichen Python-Funktionsumfang finden Sie auf der Python-Captcha-Löser -Seite. CapSkip erledigt all das als lokaler Captcha-Umgehung -Dienst auf Ihrem eigenen Rechner, sodass es Sie nichts als die Anfrage kostet, eine Seite zweimal abzurufen, um einen frischen Wert zu bekommen.