Wie Sie ein Captcha mit cURL und der rohen HTTP-API lösen

solve captcha with curl - How to Solve CAPTCHA with cURL and the Raw HTTP API

Sie brauchen kein SDK. Die CapSkip-API ist 2captcha-kompatibel, Sie lösen ein Captcha mit curl also in genau zwei Aufrufen: Schicken Sie die Aufgabe per POST an /in.php und Sie bekommen eine ID zurück, dann fragen Sie /res.php ab, bis die Antwort da ist. Alles läuft auf 127.0.0.1:8080, es gibt also keinen entfernten Endpunkt und nichts wird pro Lösung abgerechnet. Diese Anleitung enthält die genauen Parameter für jeden Captcha-Typ, die JSON-Antwortformate und ein Skript, das Sie direkt ins Terminal einfügen können.

Was Sie brauchen

  • Die laufende CapSkip-App mit gestartetem lokalem Dienst. Port- und Schlüsseleinstellungen stehen im Einrichtungsanleitung.
  • curl. Es liegt macOS, jeder Linux-Distribution und Windows 10 ab Build 1803 bei.
  • jq wenn Sie Felder aus den JSON-Antworten ziehen möchten. Optional, aber damit werden die Beispiele zu Einzeilern.

Die Schlüsselprüfung ist standardmäßig aus, es funktioniert also jede nicht leere Zeichenkette im Feld key. Schicken Sie lieber etwas als nichts: Ein leerer Schlüssel liefert ERROR_WRONG_USER_KEY.

Damit ist die Abhängigkeitsliste komplett, denn die ganze API besteht aus zwei Endpunkten:

EndpunktWas er tutLiefert
/in.phpReicht eine Aufgabe einEine numerische Captcha-ID
/res.phpFragt, ob diese ID fertig istDie Antwort, oder CAPCHA_NOT_READY

Beide akzeptieren GET oder POST. POST ist die bessere Gewohnheit, denn eine Seiten-URL mit Query-Parametern schneidet eine GET-Anfrage stillschweigend beim ersten unkodierten Und-Zeichen ab.

Schritt 1: Aufgabe einreichen

reCAPTCHA v2 ist das kürzeste Beispiel. Zwei Werte bestimmen den Auftrag: der sitekey von der Seite und die URL der Seite, auf der sie sitzt.

# No install step. curl is already on your machine.
curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha"

OK|2122988149   # the number after the pipe is your captcha ID

Achten Sie auf den Parameternamen. reCAPTCHA verwendet googlekey. Turnstile verwendet sitekey. Das Senden von sitekey zu userrecaptcha ist der mit Abstand häufigste Grund für eine Antwort mit ERROR_GOOGLEKEY .

Schritt 2: Ergebnis abfragen

Erst warten, dann fragen. Sofortiges Abfragen verbrennt nur eine Anfrage und liefert CAPCHA_NOT_READY.

sleep 15

curl -X POST http://127.0.0.1:8080/res.php \
  -d "key=YOUR_API_KEY" \
  -d "action=get" \
  -d "id=2122988149"

OK|03AGdBq26...   # the token, ready to inject into the form

Zwei Dinge an /res.php , über die Leute stolpern. Er liefert CAPCHA_NOT_READY solange die Aufgabe noch läuft, was kein Fehler ist und heißt: weiter abfragen. Und jedes Ergebnis lässt sich nur einmal lesen, speichern Sie die Antwort also sofort. Ein zweites Lesen derselben ID kommt leer zurück.

Wie lange Sie bis zur ersten Abfrage warten, hängt vom Typ ab:

TypErste Abfrage nach
Bild1 Sekunde
reCAPTCHA v215 bis 20 Sekunden
reCAPTCHA v310 bis 15 Sekunden
GeeTest v3etwa 5 Sekunden

json=1 hinzufügen, damit Sie die Antwort parsen können

Das reine Textformat ist gut für einen Menschen am Terminal und unhandlich für ein Skript. Hängen Sie json=1 an einen der beiden Endpunkte, und Sie bekommen stattdessen ein stabiles Objekt.

// in.php with json=1
{"status": 1, "request": "2122988149"}

// res.php with json=1, once it is solved
{"status": 1, "request": "03AGdBq26..."}

// res.php with json=1, still working
{"status": 0, "request": "CAPCHA_NOT_READY"}

status ist 1 bei Erfolg und 0 bei allem anderen, und der interessante Wert steht immer in request. Damit wird die ganze Sache zu zwei jq -Ausdrücken.

Alle Methoden in einer Tabelle

Neun Captcha-Typen, fünf method-Werte. Varianten sind zusätzliche Parameter, keine neuen Endpunkte.

TypmethodErforderliche Parameter
Bild, hochgeladene Dateipostfile
Bild, base64base64body
reCAPTCHA v2userrecaptchagooglekey, pageurl
reCAPTCHA v2 Invisibleuserrecaptchaplus invisible=1
reCAPTCHA Enterpriseuserrecaptchaplus enterprise=1
reCAPTCHA v3userrecaptchaplus version=v3, action
Turnstile-Widgetturnstilesitekey, pageurl
Turnstile-Challenge-Seiteturnstileplus data, pagedata
GeeTest v3geetestgt, challenge, pageurl

Ein Bild geht als Formular-Upload oder als base64 im Body hoch:

# File upload. Note the @ in front of the path. Use -F for every
# field here: curl refuses to mix -F and -d in one request.
curl -X POST http://127.0.0.1:8080/in.php \
  -F "key=YOUR_API_KEY" -F "method=post" -F "[email protected]"

# Or send the bytes inline, already base64 encoded.
curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=base64" \
  --data-urlencode "body=$(base64 < captcha.png | tr -d '\n')"

Verwenden --data-urlencode für alles, was +, / oder =enthält. Base64-Daten enthalten alle drei, und ein einfaches -d verstümmelt sie.

Turnstile liefert auch einen User Agent zurück

Cloudflare bindet das Token an den Browser-Fingerabdruck, der es erzeugt hat. Ein Token, das Sie mit einem anderen User Agent abschicken, wird deshalb abgelehnt, obwohl es an sich gültig ist. Die rohe API gibt Ihnen den verwendeten Wert an zwei Stellen:

  • Mit json=1, als Feld userAgent in der Antwort.
  • Im Textmodus als Antwort-Header X-Turnstile-User-Agent response-Header.
# -i prints the headers, which is where the user agent lives
# when you are not using json=1.
curl -i -X POST http://127.0.0.1:8080/res.php \
  -d "key=YOUR_API_KEY" -d "action=get" -d "id=2122988149"

X-Turnstile-User-Agent: Mozilla/5.0 ...
OK|0.abc123...

Ganzseitige Challenges brauchen außerdem data (den cData-Wert) und pagedata (chlPageData), direkt vor dem Absenden von der Seite gelesen. Der Widget-Modus braucht keines von beidem. Die Seite Turnstile-Löser erklärt den Unterschied ausführlicher.

GeeTest antwortet mit drei Feldern, nicht mit einem

GeeTest liefert kein einzelnes Token. Fordern Sie JSON an, und Sie bekommen die drei Werte, die das Frontend der Seite selbst zurücksenden würde.

{
  "status": 1,
  "request": {
    "geetest_challenge": "...",
    "geetest_validate":  "...",
    "geetest_seccode":   "..."
  }
}

The gt Der Wert ist pro Website konstant. Der Wert challenge -Wert ist einmalig und stirbt nach etwa einer Minute. Holen Sie ihn direkt vor dem Absenden, nie am Anfang eines langen Skripts.

Eine Lösung über einen Proxy leiten

Zwei Parameter, an denselben /in.php -Aufruf angehängt:

curl -X POST http://127.0.0.1:8080/in.php \
  -d "key=YOUR_API_KEY" \
  -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha" \
  -d "proxy=login:[email protected]:3128" \
  -d "proxytype=HTTPS"

proxytype nimmt HTTP, HTTPS, SOCKS5 oder SOCKS5H. Proxys gelten nur für reCAPTCHA, Turnstile und GeeTest. Das Lösen von Bildern liest Pixel, die Sie schon haben, und fasst die Zielseite nie an, ein Proxy bringt dort also nichts.

Ein vollständiges Skript

Einreichen, mit Obergrenze abfragen, Token ausgeben. Rund zwanzig Zeilen, ohne Abhängigkeiten außer curl.

#!/usr/bin/env bash
set -euo pipefail

API="http://127.0.0.1:8080"
KEY="YOUR_API_KEY"

# Submit and keep only the part after the pipe.
ID=$(curl -s -X POST "$API/in.php" \
  -d "key=$KEY" -d "method=userrecaptcha" \
  -d "googlekey=YOUR_SITEKEY" \
  -d "pageurl=https://example.com/page-with-recaptcha" | cut -d'|' -f2)

sleep 15

# Poll every 5s, give up after 20 tries so this cannot hang forever.
for _ in $(seq 20); do
  R=$(curl -s -X POST "$API/res.php" -d "key=$KEY" -d "action=get" -d "id=$ID")
  [ "$R" = "CAPCHA_NOT_READY" ] || { echo "${R#OK|}"; exit 0; }
  sleep 5
done

echo "timed out waiting for $ID" >&2; exit 1

The || { ...; exit 0; } -Zweig greift bei allem, was nicht CAPCHA_NOT_READYist, Fehlercodes eingeschlossen. Das ist Absicht: Ein Fehler heißt anhalten, nicht weiter abfragen.

Fehler, die Ihnen auf dieser Ebene begegnen

CodeBedeutetBeheben
ERROR_WRONG_USER_KEYDer Schlüssel fehlte oder war leerSenden Sie einen beliebigen nicht leeren key
ERROR_WRONG_METHODFalscher method oder actionSchreibweise mit der Tabelle oben abgleichen
ERROR_BAD_PARAMETERSEin erforderlicher Parameter fehltMit der Spalte der erforderlichen Parameter oben vergleichen
ERROR_GOOGLEKEYThe googlekey -Wert wurde abgelehntSie haben wahrscheinlich sitekey stattdessen gesendet
ERROR_PAGEURLThe pageurl -Wert wurde abgelehntSchema angeben und POST statt GET verwenden
CAPCHA_NOT_READYLäuft nochKein Fehler. Dieselbe ID weiter abfragen
Leere AntwortSchon gelesen, oder es gibt die ID nichtErgebnisse sind einmal lesbar. Speichern Sie das erste

Der genaue Wortlaut jedes Codes, den die API zurückgeben kann, steht in der API-Dokumentation.

Wann Sie curl verlassen sollten

Rohes HTTP ist perfekt für einen Schnelltest, eine Shell-Pipeline oder eine Sprache ohne offiziellen Client. Für Anwendungscode sind die CapSkip SDKs die Abhängigkeit vor allem aus einem Grund wert: Sie fragen nicht in festem Intervall ab. Sie starten bei 250 ms und gehen zurück auf pollingInterval, eine Lösung kommt also meist schneller zurück als bei der handgeschriebenen Schleife oben, die jedes Mal ihre vollen 15 Sekunden aussitzt.

Sie verwandeln außerdem die Fehlerzeichenketten in typisierte Ausnahmen und kümmern sich für Sie um den Turnstile-User-Agent und die dreiteilige GeeTest-Antwort. Offizielle Clients gibt es für Python, Node.js, PHP und .NET.

Häufig gestellte Fragen

Kann ich GET statt POST verwenden?

Ja, beide Endpunkte akzeptieren es. Der Haken: Eine pageurl mit eigener Query-Zeichenkette wird beim ersten unkodierten Und-Zeichen abgeschnitten, und Sie bekommen ERROR_PAGEURL oder eine Lösung für die falsche Seite. Wenn es GET sein muss, schicken Sie die URL vorher durch --data-urlencode .

Welchen API-Schlüssel soll ich senden?

Eine beliebige nicht leere Zeichenkette. Die Schlüsselprüfung ist standardmäßig aus, weil der Dienst nur auf localhost lauscht, also funktioniert key=capskip problemlos. Vorhanden sein muss er trotzdem: Lassen Sie ihn weg, bekommen Sie ERROR_WRONG_USER_KEY statt einer Lösung.

Funktioniert das aus Windows PowerShell?

Verwenden curl.exe explizit. In PowerShell ist curl ein Alias für Invoke-WebRequest, das -d nicht versteht und einen Parameterfehler wirft, der wie ein API-Problem aussieht. Wenn Sie curl.exe schreiben, umgehen Sie den Alias.

Kann ich mehrere Lösungen gleichzeitig laufen lassen?

Ja. Reichen Sie so viele Aufgaben ein, wie Sie möchten, und fragen Sie jede ID unabhängig ab. Nichts serialisiert sie, und es gibt kein Kontingent pro Minute, weil die Arbeit auf Ihrer eigenen Hardware passiert und nicht in einer gemeinsamen Warteschlange.

Zusammenfassung

Schicken Sie die Aufgabe per POST an /in.php, merken Sie sich die ID, warten Sie die zum Typ passende Verzögerung ab und fragen Sie dann /res.php ab, bis Sie etwas anderes bekommen als CAPCHA_NOT_READY. Ergänzen Sie json=1 wenn ein Skript die Antwort liest. Achten Sie auf die zwei Namensfallen: googlekey für reCAPTCHA gegen sitekey für Turnstile, und darauf, dass ein Ergebnis nur einmal gelesen werden kann.

Weil es ein Captcha-Löser ist, der auf Ihrem eigenen Rechner läuft, hat die Schleife oben kein Kontingent zu beachten und kein Guthaben aufzuladen. Richten Sie sie auf localhost, und die einzige Grenze ist, wie schnell Ihre CPU die Warteschlange abarbeitet.