Guzzle mit der CAPTCHA-Aufgaben-API verwenden
Verwenden Sie Guzzle 7, um einen Task zu erstellen, und fragen Sie anschließend seine ID ab, bis der Status ready oder failed lautet. Bewahren Sie die requestId auf, falls etwas schiefgeht: Ein Verbindungstimeout beweist nicht, dass die Task-Erstellung fehlgeschlagen ist.
Dies ist eine REST-Integration, kein offizielles PHP-SDK.
Auf dieser Seite
reCAPTCHA-Anfrage vorbereiten
- Installieren Sie Guzzle 7 mit Composer. Der Installationsbefehl steht am Anfang des Beispiels.
- Setzen Sie SOLVETHREE_API_KEY auf Ihren Workspace-API-Schlüssel und SOLVETHREE_PROXY auf die Proxy-URL. Belassen Sie den Schlüssel auf dem Server.
- Erstellen Sie in der Konsole ein aktives Profil für Ihre Zielwebsite, bevor Sie einen Lösungsversuch anfordern. Siehe Websiteprofil einrichten.
- Ersetzen Sie accounts.example.com und login durch den Zielhostnamen und die Aktion. Das Feld site erwartet einen Hostnamen, keine vollständige URL.
Das Beispiel fordert reCAPTCHA Enterprise v3 an, den Standardwert für recaptchaType. Fügen Sie keine Felder type oder url hinzu. Es übergibt einen Proxy; wenn Sie stattdessen proxyCandidates verwenden, lassen Sie proxy vollständig weg.
Einmal erstellen, dann innerhalb eines festen Zeitbudgets abfragen
<?php
// composer require guzzlehttp/guzzle:^7
require __DIR__.'/vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://api.solvethree.com/v1/',
'headers' => ['Authorization' => 'Bearer '.getenv('SOLVETHREE_API_KEY'), 'Accept' => 'application/json'],
'allow_redirects' => false,
'http_errors' => false,
]);
$input = ['site' => 'accounts.example.com', 'action' => 'login',
'proxy' => getenv('SOLVETHREE_PROXY'), 'requestId' => bin2hex(random_bytes(16))];
$deadline = microtime(true) + 180;
$call = function (string $method, string $path, array $options = []) use ($client, $deadline): array {
$remaining = $deadline - microtime(true);
if ($remaining <= 0) throw new RuntimeException('Local deadline reached');
$response = $client->request($method, $path, $options + ['timeout' => min(25, $remaining), 'connect_timeout' => min(10, $remaining)]);
if ($response->getStatusCode() < 200 || $response->getStatusCode() >= 300) {
throw new RuntimeException('API HTTP '.$response->getStatusCode());
}
return json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
};
$id = null;
try {
$result = $call('POST', 'tasks?waitMs=0', ['json' => $input]);
$id = $result['id'];
while (in_array($result['status'], ['pending', 'solving'], true)) {
$result = $call('GET', 'tasks/'.rawurlencode($id).'?waitMs=15000');
if (in_array($result['status'], ['pending', 'solving'], true)) usleep(1000000);
}
if ($result['status'] !== 'ready') {
throw new RuntimeException('Task failed: '.($result['errorCode'] ?? 'unknown'));
}
echo 'Ready task: '.$id.PHP_EOL;
// Submit $result['solution']['token'] with userAgent/secChUa and the same proxy.
} catch (Throwable $error) {
fwrite(STDERR, 'Recovery requestId='.$input['requestId'].' taskId='.($id ?? 'unknown').PHP_EOL);
throw $error;
}Der Client authentifiziert sich mit einem Bearer-Schlüssel. Seine base_uri endet auf /v1/, und die Anfragepfade sind relativ, sodass dieses API-Präfix erhalten bleibt. Die Option json von Guzzle sendet die Task-Eingaben als JSON.
Die Hilfsfunktion führt einen einzelnen POST zur Erstellung aus. Anschließend fragt sie die zurückgegebene Task-ID ab, solange status den Wert pending oder solving hat. Erstellung und Abfragen teilen sich ein Zeitbudget von 180 Sekunden; jeder HTTP-Aufruf ist auf die verbleibende Zeit begrenzt, mit maximalen Anfrage- und Verbindungstimeouts von 25 bzw. 10 Sekunden. Eine neue Abfrage startet das Gesamtzeitbudget nicht neu.
Weiterleitungen sind deaktiviert. Wenn http_errors auf false gesetzt ist, kann die Hilfsfunktion Antworten außerhalb von 2xx explizit prüfen, bevor sie die Nutzdaten einer erfolgreichen Antwort dekodiert; Verbindungsfehler oder Timeouts werden dadurch nicht unterdrückt.
- Eine HTTP-Antwort außerhalb von 2xx löst einen API-HTTP-Fehler aus. Analysieren Sie Status und Body der Antwort, statt sie als fehlgeschlagenen Lösungsversuch zu behandeln.
- Ein Task mit dem Endstatus failed beendet die Abfragen. Das Beispiel löst eine Ausnahme mit seinem errorCode aus; prüfen Sie auch das Feld error des Tasks auf die Diagnosemeldung. Fehlgeschlagene Lösungsversuche werden erstattet.
- Nur ready enthält eine verwendbare Lösung. Die ausgegebene Zeile „Ready task“ meldet die Bereitschaft des Tasks, nicht die Annahme durch die Zielwebsite.
Eine Anfrage nach Zeitüberschreitung wiederaufnehmen, ohne für eine weitere Aufgabe zu bezahlen
Speichern Sie die generierte requestId und die exakten Task-Eingaben, bevor Sie POST senden. Der catch-Block gibt requestId und, falls die Erstellung eine zurückgegeben hat, taskId aus. Diese Ausgabe hilft bei der Wiederherstellung, ersetzt aber nicht das Speichern der Anfrage vor dem Senden.
- 1.
Wenn Sie eine Task-ID haben, rufen Sie diesen Task ab
Verwenden Sie GET /v1/tasks/:id, um seinen Status zu prüfen. Das Erreichen der lokalen Frist der Hilfsfunktion belegt nicht, dass der entfernte Task fehlgeschlagen ist.
- 2.
Wenn die Erstellung ohne Rückgabe einer ID das Zeitlimit überschritten hat, stellen Sie sie mit requestId wieder her
Senden Sie dieselbe Task-Anfrage mit der gespeicherten requestId. Bei übereinstimmenden Eingaben wird der vorhandene Task zurückgegeben; andere Eingaben mit dieser ID führen zu einem Konflikt.
- 3.
Skript nicht als Abkürzung zur Wiederherstellung erneut ausführen
Jeder Durchlauf generiert eine neue requestId. Fügen Sie keine automatische POST-Wiederholung hinzu, die eine weitere ID generiert, und wiederholen Sie ungültige Eingaben nicht blind unverändert.
Token über denselben Proxy übermitteln
Das Beispiel endet, bevor es das Ziel kontaktiert. Übermitteln Sie solution.token – nicht die Task-ID – und verwenden Sie die zurückgegebenen Werte solution.userAgent und solution.secChUa als Header User-Agent und Sec-CH-UA der Zielanfrage.
Der Proxy im JSON des Tasks teilt solvethree mit, welchen Proxy es für den Lösungsversuch verwenden soll. Er konfiguriert weder die Verbindung von Guzzle zur API noch Ihre spätere Anfrage an das Ziel. Konfigurieren Sie die Zielanfrage separat so, dass sie denselben Proxy verwendet.
Verwenden Sie für die Zielanfrage einen separaten Client, damit der standardmäßige Authorization-Header des API-Clients nicht an die Website gesendet wird. Halten Sie Token, zurückgegebene Browseridentität, Proxy und vorgesehenes Ziel zusammen. Ein fertiges Token kann weiterhin abgelehnt werden, wenn die nachfolgende Anfrage nicht dazu passt.
Quellen und API-Referenz
Führe deinen ersten Task aus.
Starte mit $5 Workspace-Guthaben.