Résoudre reCAPTCHA Enterprise avec PHP

Par solvethree3 min de lecture

Vous pouvez appeler solvethree directement depuis PHP. L’exemple ci-dessous demande un jeton reCAPTCHA v3 Enterprise, suit la tâche jusqu’à sa fin et s’arrête si la résolution échoue.

Sur cette page

Avant l’exécution

Utilisez PHP 8+ avec l’extension cURL. Exécutez le code sur votre serveur, avec l’extension cURL activée.

  • Créez un profil de site actif pour votre nom d’hôte cible dans la console. Consultez la configuration du profil de site.
  • Définissez SOLVETHREE_API_KEY sur la clé API de votre espace de travail et SOLVETHREE_PROXY sur l’URL de votre proxy HTTP(S).
  • Remplacez accounts.example.com et login par votre nom d’hôte et l’action utilisée par la page. Pour site, utilisez un nom d’hôte, sans schéma ni chemin.

Créer la tâche et attendre le résultat

Enregistrez le code dans solve.php et exécutez php solve.php.

PHP 8 · solve.php
<?php
// Requires PHP 8+ with the cURL extension.
$apiKey = getenv('SOLVETHREE_API_KEY');
$proxy = getenv('SOLVETHREE_PROXY');
if (!$apiKey || !$proxy) throw new RuntimeException('Set the API key and proxy');

function api(string $path, ?array $body = null): array {
    global $apiKey, $deadline;
    $remaining = $deadline - microtime(true);
    if ($remaining <= 0) throw new RuntimeException("Keep the task ID and resume polling");
    $curl = curl_init('https://api.solvethree.com/v1' . $path);
    curl_setopt_array($curl, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT_MS => min(30000, max(1, (int) ceil($remaining * 1000))),
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey, 'Content-Type: application/json'],
    ]);
    if ($body !== null) {
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($body, JSON_THROW_ON_ERROR));
    }
    $raw = curl_exec($curl);
    $error = curl_error($curl);
    $status = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
    curl_close($curl);
    if ($raw === false) throw new RuntimeException('Connection failed: ' . $error);
    if ($status < 200 || $status >= 300) throw new RuntimeException('API HTTP ' . $status);
    return json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
}

$requestId = bin2hex(random_bytes(16)); // Save this with the task inputs for recovery.
$deadline = microtime(true) + 180;
$task = api('/tasks?waitMs=0', [
    'site' => 'accounts.example.com', 'action' => 'login',
    'proxy' => $proxy, 'requestId' => $requestId,
]);
while (in_array($task['status'], ['pending', 'solving'], true)) {
    if (microtime(true) >= $deadline) throw new RuntimeException('Keep the task ID and resume polling');
    $task = api('/tasks/' . rawurlencode($task['id']) . '?waitMs=15000');
    if (in_array($task['status'], ['pending', 'solving'], true)) usleep(1000000);
}
if ($task['status'] !== 'ready') throw new RuntimeException(
    ($task['errorCode'] ?? 'Unexpected task state') . ': ' . ($task['error'] ?? '')
);
$solution = $task['solution'];
// Use $solution['token'], ['userAgent'] and ['secChUa'] with the same proxy.
echo 'Ready task: ' . $task['id'] . PHP_EOL;

La requête POST utilise waitMs=0 pour renvoyer immédiatement une tâche. Chaque requête GET attend ensuite jusqu’à 15 secondes une mise à jour. La boucle continue pour pending ou solving, et s’arrête à ready ou failed.

La requête utilise Enterprise v3 par défaut. Pour la version v3 standard, ajoutez recaptchaType: v3. N’incluez pas type ni url dans le corps d’une tâche reCAPTCHA.

Utiliser le jeton dans votre application

Le jeton se trouve dans $solution['token']. L’identifiant de tâche affiché par le programme sert à récupérer la tâche ; utilisez la valeur du jeton dans le champ CAPTCHA de votre application.

Utilisez $solution['userAgent'] comme User-Agent et $solution['secChUa'] comme sec-ch-ua dans la requête cible.

Envoyez cette requête via le même proxy que celui utilisé pour la résolution. Vérifiez ensuite la réponse de l’application : la génération d’un jeton ne prouve pas que la cible a accepté la requête.

Si la requête échoue

Une tâche ayant échoué contient errorCode et error ; l’exemple s’arrête et les affiche. Les résolutions échouées sont remboursées. Une erreur HTTP telle que 401 ou 402 correspond à un problème de requête distinct : consultez la référence des erreurs de l’API avant de réessayer.

Conservez le requestId et les paramètres exacts de la tâche si vous devez la récupérer après un dépassement de délai ou un redémarrage du processus. Si vous disposez de l’identifiant de tâche, interrogez-la. Sinon, renvoyez les paramètres d’origine avec le même requestId. Un simple redémarrage du programme génère un autre identifiant et peut créer une autre résolution facturable.

L’appelant cesse d’attendre une fois son délai dépassé ; cela n’annule pas une tâche déjà créée. Consultez la procédure complète d’interrogation périodique et de récupération après dépassement de délai.

Lancez votre première tâche.

Démarrez avec $5 de crédit dans votre espace de travail.

Créer un espace de travail
Résoudre reCAPTCHA Enterprise avec PHP · solvethree