Resuelve reCAPTCHA Enterprise con PHP

Por solvethree3 min de lectura

Puedes llamar a solvethree directamente desde PHP. El siguiente ejemplo solicita un token de reCAPTCHA v3 Enterprise, sigue la tarea hasta que finaliza y se detiene si la resolución falla.

En esta página

Antes de ejecutarlo

Usa PHP 8+ con la extensión cURL. Ejecútalo en tu servidor con la extensión cURL habilitada.

  • Crea un perfil de sitio activo para el nombre de host de destino en la consola. Consulta la configuración de perfiles de sitio.
  • Establece SOLVETHREE_API_KEY con la clave de API de tu espacio de trabajo y SOLVETHREE_PROXY con la URL de tu proxy HTTP(S).
  • Sustituye accounts.example.com y login por tu nombre de host y la acción que utiliza la página. Usa un nombre de host para site, sin esquema ni ruta.

Crea la tarea y espera el resultado

Guarda el código como solve.php y ejecuta 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;

El POST usa waitMs=0 para devolver una tarea inmediatamente. Después, cada GET espera hasta 15 segundos a que haya una actualización. El bucle continúa mientras el estado sea pending o solving y se detiene en ready o failed.

La solicitud usa Enterprise v3 de forma predeterminada. Para v3 estándar, añade recaptchaType: v3. No incluyas type ni url en el cuerpo de una tarea de reCAPTCHA.

Usa el token en tu aplicación

El token es $solution['token']. El ID de tarea que imprime el programa sirve para recuperar la tarea; usa el valor del token en el campo CAPTCHA de tu aplicación.

Usa $solution['userAgent'] como User-Agent y $solution['secChUa'] como sec-ch-ua en la solicitud de destino.

Envía esa solicitud a través del mismo proxy que se utilizó para la resolución. Después, comprueba la respuesta de la aplicación: que se haya generado un token no demuestra que el destino haya aceptado la solicitud.

Si la solicitud falla

Una tarea fallida incluye errorCode y error; el ejemplo se detiene y los muestra. Las resoluciones fallidas se reembolsan. Un error HTTP como 401 o 402 es un problema distinto de la solicitud: consulta la referencia de errores de la API antes de volver a intentarlo.

Conserva el requestId y los datos de entrada exactos de la tarea si necesitas recuperarla tras agotar el tiempo de espera o reiniciar el proceso. Si tienes el ID de la tarea, consúltala. De lo contrario, vuelve a enviar los datos de entrada originales con el mismo requestId. Reiniciar el programa sin más genera otro ID y puede crear otra resolución facturable.

El cliente deja de esperar cuando alcanza su límite de tiempo; eso no cancela una tarea ya creada. Consulta la recuperación tras consultas periódicas y tiempos de espera agotados para ver la secuencia completa.

Ejecuta tu primera tarea.

Empieza con $5 de crédito en tu espacio de trabajo.

Crear un espacio de trabajo
Resuelve reCAPTCHA Enterprise con PHP · solvethree