reCAPTCHA mit aiohttp lösen und übermitteln

Von solvethree4 Min. Lesezeit

Verwenden Sie aiohttp direkt mit der REST-API: Erstellen Sie eine Aufgabe, fragen Sie sie ab, bis sie bereit ist, und übermitteln Sie anschließend solution.token an die Zielseite. Halten Sie API- und Zielanfragen in getrennten Sitzungen, damit Ihr Workspace-Bearer-Token niemals an die Zielseite gelangt.

Das Beispiel erfordert Python 3.11+ und führt Erstellung, Abfrage und Übermittlung an die Zielseite innerhalb eines gemeinsamen Zeitlimits von 180 Sekunden aus. Das ist ein Anwendungszeitlimit, keine zugesicherte Lösungszeit.

Auf dieser Seite

Website, Proxy und Zielanfrage festlegen

  • Setzen Sie SOLVETHREE_API_KEY auf Ihren Workspace-API-Schlüssel. Bewahren Sie ihn auf dem Server auf.
  • Setzen Sie SOLVETHREE_PROXY auf die Proxy-URL, die der Dienst zum Lösen verwenden soll. Die Übermittlung an die Zielseite verwendet denselben Proxy.
  • Ersetzen Sie accounts.example.com und die Aktion login durch den Hostnamen und die Aktion Ihrer Integration. Für die Website muss ein aktives Profil in Ihrem Workspace verfügbar sein; richten Sie das Profil ein, bevor Sie Aufgaben erstellen.
  • Ersetzen Sie die Anmelde-URL der Zielseite und die Formulardaten durch die tatsächliche Anwendungsanfrage. Das Beispiel sendet nur g-recaptcha-response; ergänzen Sie die weiteren von Ihrer Zielseite benötigten Felder und verwenden Sie das erwartete Tokenfeld.

Die Aufgabe sendet site, action und einen einzelnen proxy. Standardmäßig wird reCAPTCHA Enterprise v3 verwendet; fügen Sie keine Felder namens type oder url hinzu. Wenn der Zielablauf Cookies aus einer früheren Anfrage benötigt, führen Sie diese Anfragen über die Zielsitzung aus – das Beispiel beginnt mit einer neuen Sitzung.

Einmal erstellen, abfragen, dann übermitteln

aiohttp · Einmal erstellen, per Polling abfragen und absenden
# pip install aiohttp
import asyncio
import os
import uuid
from urllib.parse import urlsplit, unquote
import aiohttp

async def main():
    api = "https://api.solvethree.com/v1"
    proxy = os.environ["SOLVETHREE_PROXY"]
    task = {"site": "accounts.example.com", "action": "login", "proxy": proxy, "requestId": str(uuid.uuid4())}
    task_id = None
    try:
        async with asyncio.timeout(180):
            async with aiohttp.ClientSession(headers={"Authorization": "Bearer " + os.environ["SOLVETHREE_API_KEY"]}) as client:
                async with client.post(api + "/tasks", params={"waitMs": 0}, json=task, allow_redirects=False) as response:
                    response.raise_for_status()
                    if response.status >= 300: raise RuntimeError("Unexpected API redirect")
                    result = await response.json()
                task_id = result["id"]
                while result["status"] in ("pending", "solving"):
                    async with client.get(api + "/tasks/" + task_id, params={"waitMs": 15000}, allow_redirects=False) as response:
                        response.raise_for_status()
                        if response.status >= 300: raise RuntimeError("Unexpected API redirect")
                        result = await response.json()
                    if result["status"] in ("pending", "solving"): await asyncio.sleep(1)
                if result["status"] != "ready":
                    raise RuntimeError("Task failed: " + str(result.get("errorCode", "unknown")))
            solution = result["solution"]
            # A separate session prevents the API Bearer header reaching the target.
            proxy_url = urlsplit(proxy)
            netloc = proxy_url.netloc.rsplit("@", 1)[-1]
            server = f"{proxy_url.scheme}://{netloc}"
            auth = aiohttp.BasicAuth(unquote(proxy_url.username), unquote(proxy_url.password or "")) if proxy_url.username else None
            async with aiohttp.ClientSession() as target:
                async with target.post("https://accounts.example.com/login", proxy=server, proxy_auth=auth,
                    headers={"User-Agent": solution["userAgent"], "sec-ch-ua": solution["secChUa"]},
                    data={"g-recaptcha-response": solution["token"]}, allow_redirects=False) as response:
                    print("Application HTTP status:", response.status)
    except TimeoutError:
        print("Timed out; recover requestId", task["requestId"], "taskId", task_id)
        raise

asyncio.run(main())

Dies ist ein direkter asynchroner REST-Aufruf, keine asynchrone Methode des offiziellen Python-SDKs. Das Beispiel sendet einen einzigen POST zur Erstellung an /v1/tasks, speichert die zurückgegebene id und fragt diese Aufgabe mit GET-Anfragen ab. pending und solving setzen die Schleife fort; ready erlaubt die Übermittlung; eine Aufgabe mit dem Status failed beendet die Schleife.

Der proxy im Aufgabeninhalt teilt solvethree mit, welcher Proxy verwendet werden soll. Die aiohttp-Argumente proxy und proxy_auth erscheinen nur beim HTTP-Aufruf an die Zielseite – nicht bei den API-Aufrufen. Das Beispiel trennt Proxy-Zugangsdaten von der Proxyserver-URL und übermittelt das Token mit den zurückgegebenen Werten userAgent und secChUa.

Die Sitzungen sind bewusst getrennt: Nur die API-Sitzung enthält den Authorization-Header. Weiterleitungen sind deaktiviert, und API-Weiterleitungen werden als Fehler behandelt, statt ihnen zu folgen.

Eine API-Anfrage gibt einen HTTP-Fehler zurück.

Das Beispiel prüft den HTTP-Status, bevor es die Nutzdaten einer erfolgreichen Antwort liest.

Probiere Folgendes: Behandeln Sie den HTTP-Fehler getrennt vom Fehlschlagen einer Aufgabe. Korrigieren Sie ungültige Eingaben oder Autorisierungsprobleme vor einem erneuten Versuch.

Die Aufgabe erreicht den Status failed.

Prüfen Sie errorCode und error in der Aufgabenantwort. Das Beispiel löst eine Ausnahme nur mit errorCode aus.

Probiere Folgendes: Beenden Sie die Abfrage dieser Aufgabe und beheben Sie die gemeldete Ursache. Beheben Sie die gemeldete Ursache vor einem erneuten Versuch.

Die Aufgabe hat den Status ready, aber die Anwendung lehnt die Anfrage ab.

Prüfen Sie das ausgehende Tokenfeld, die Ziel-URL, die zurückgegebene Browseridentität und den Proxy sowie alle erforderlichen Formularfelder oder Cookies.

Probiere Folgendes: Übermitteln Sie solution.token mit der zurückgegebenen Identität über denselben Proxy. Bewerten Sie die Anwendungsantwort anhand der Erfolgskriterien dieser Zielseite – der ausgegebene HTTP-Status allein belegt keine Annahme.

Nach einer Zeitüberschreitung fortfahren, ohne eine weitere Lösung zu kaufen

Eine Zeitüberschreitung bei der Erstellung beweist nicht, dass die Erstellung fehlgeschlagen ist. Das Beispiel behält die ursprünglichen Eingaben in task bei und gibt dessen requestId sowie task_id aus, wenn das Zeitlimit abläuft. Diese Variablen bleiben nur erhalten, solange der Prozess läuft; die ausgegebenen IDs sind kein vollständiger Datensatz für die Wiederaufnahme.

  1. 1.

    Ursprüngliche Anfrage vor der Erstellung speichern

    Um nach Neustarts fortfahren zu können, bewahren Sie den vollständigen Aufgabeninhalt einschließlich requestId und proxy sicher auf. Das Beispiel erzeugt bei jedem Durchlauf eine neue UUID; ein einfaches erneutes Ausführen erstellt daher eine neue logische Anfrage.

  2. 2.

    Bestehende Aufgabe fortsetzen

    Wenn Sie task_id haben, rufen Sie diese Aufgabe ab. Falls die Erstellung das Zeitlimit überschritten hat, bevor Sie eine ID erhalten haben, wiederholen Sie die Erstellung mit dem gespeicherten, unveränderten Aufgabeninhalt und derselben requestId. Die API gibt die bestehende Aufgabe zurück; geänderte Eingaben bei Wiederverwendung der ID führen zu einem Konflikt.

  3. 3.

    Prüfen, ob die Übermittlung bereits erfolgt ist

    Das Zeitlimit gilt auch für den POST an die Zielseite. Falls diese Anfrage das Zeitlimit überschritten hat, prüfen Sie vor einer erneuten Übermittlung das Ergebnis in der Anwendung: Sie könnte die Anfrage erhalten haben, obwohl Ihr Client keine Antwort erhalten hat. Die Wiederaufnahme der solvethree-Aufgabe klärt nicht, was auf der Zielseite geschehen ist.

Führe deinen ersten Task aus.

Starte mit $5 Workspace-Guthaben.

Workspace erstellen
reCAPTCHA mit aiohttp lösen und übermitteln · solvethree