使用 PHP 求解 reCAPTCHA Enterprise

作者:solvethree阅读需 1 分钟

你可以直接从 PHP 调用 solvethree。下面的示例会请求 reCAPTCHA v3 Enterprise 令牌,持续跟踪任务直至完成,并在求解失败时停止。

本页内容

运行前的准备

使用带有 cURL 扩展的 PHP 8+。在服务器上运行,并启用 cURL 扩展。

  • 在控制台中为目标主机名创建有效的站点配置文件。请参阅站点配置文件设置。
  • 将 SOLVETHREE_API_KEY 设为你的工作区 API 密钥,将 SOLVETHREE_PROXY 设为你的 HTTP(S) 代理 URL。
  • 将 accounts.example.com 和 login 替换为你的主机名和页面使用的操作。site 应使用主机名,不含协议或路径。

创建任务并等待结果

将代码保存为 solve.php,然后运行 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;

POST 使用 waitMs=0 立即返回任务。随后每次 GET 最多等待 15 秒以获取更新。状态为 pending 或 solving 时继续循环,为 ready 或 failed 时停止。

请求默认使用 Enterprise v3。如需标准 v3,请添加 recaptchaType: v3。不要在 reCAPTCHA 任务请求体中包含 type 和 url。

在应用中使用令牌

令牌为 $solution['token']。程序输出的任务 ID 用于获取任务;请在应用的 CAPTCHA 字段中使用令牌值。

在目标请求中,将 $solution['userAgent'] 用作 User-Agent,将 $solution['secChUa'] 用作 sec-ch-ua。

通过求解时使用的同一代理发送该请求。然后检查应用响应:生成了令牌并不代表目标接受了请求。

请求失败时

失败的任务包含 errorCode 和 error;示例会停止并报告这些信息。求解失败会退款。401 或 402 等 HTTP 错误属于另一类请求问题,请在重试前查看 API 错误参考。

如果需要在超时或进程重启后恢复,请保留 requestId 和完全一致的任务输入。如果已有任务 ID,就轮询该任务。否则,使用相同的 requestId 重新发送原始输入。直接重启程序会生成另一个 ID,可能创建另一次计费求解。

调用方在截止时间后停止等待,但这不会取消已创建的任务。完整流程请参阅轮询与超时恢复。

运行您的第一个任务。

使用 $5 工作区额度开始体验。

创建工作区
使用 PHP 求解 reCAPTCHA Enterprise · solvethree