处理 CAPTCHA 任务轮询和超时

作者:solvethree阅读需 1 分钟

创建一个任务,保存其 ID,并轮询该任务,直到状态变为 ready、failed 或到达截止时间。客户端超时不代表任务失败,长轮询等待结束也不代表求解已停止。

本页内容

分别设置服务器等待时间和客户端超时

waitMs 控制 API 请求在响应前等待结果的时长。它是 URL 查询参数,不是任务 JSON 中的字段。创建任务时的默认值因产品而异;GET 轮询有自己的上限。

任务 API 等待设置
任务 API 等待设置
请求服务器等待时间
创建 reCAPTCHA v3 Enterprise 任务默认最多等待 15000 ms。
创建 Kasada 任务默认最多等待 75000 ms。
创建 Ticketmaster TMPT 任务默认异步执行:waitMs=0。显式设置的 waitMs 最大可为 75000。
通过 GET 获取现有任务默认不等待。显式设置的 waitMs 最大可为 15000。

为 HTTP 客户端留出足够时间,涵盖请求的服务器等待时间和网络开销。如果客户端超时短于服务器等待时间,可能会在收到任务当前状态之前中断响应。

只创建一次,并为轮询设置时限

官方 SDK 的 solve 方法只创建一次任务,然后持续轮询,直到结果就绪或出现错误。Python 提供以秒为单位的 timeout 和 poll_interval;Node.js 提供以毫秒为单位的 timeoutMs 和 pollIntervalMs。文档中的设置采用三分钟的求解时限和一秒的轮询间隔。

如需直接控制,Python 提供 create_task 和 get_task;Node.js 提供 createTask 和 getTask。请按以下顺序操作:

  1. 1.

    设置截止时间并创建一个任务

    在创建前确定总体截止时间。将 requestId 与完全一致的任务输入一起保存,以便在创建中断时恢复。若不想在创建时等待,请显式将等待时间设为零。

  2. 2.

    保存返回的任务 ID 并检查状态

    创建请求可能直接返回终态结果。状态为 ready 时返回求解结果。状态为 failed 时,检查 errorCode 和 error 并停止;失败的求解会退款。只有 pending 和 solving 需要继续轮询。

  3. 3.

    在剩余时间内查询同一个任务

    使用 GET /v1/tasks/:id,可选择设置最长 15000 ms 的长轮询等待。读取成功响应内容前,先处理非成功的 HTTP 响应。如果响应仍为 pending 或 solving,请使用同一个 ID 重复查询,不要创建另一个任务。

  4. 4.

    到达截止时间后停止

    根据剩余时间限制每次请求的时长,并为网络开销留出余量。到达截止时间后,停止本地循环并保留任务 ID 以便恢复。不要仅因客户端停止等待,就将任务标记为失败。

此请求用于查询现有任务,允许服务器等待 15 秒,客户端超时为 30 秒。将 TASK_ID 设置为已保存的 ID,并将 SOLVETHREE_API_KEY 保留在服务器上。这两个超时都不是重复轮询循环的总体截止时间。

任务 API · 获取现有任务
curl --fail-with-body --max-time 30 \
  "https://api.solvethree.com/v1/tasks/$TASK_ID?waitMs=15000" \
  -H "Authorization: Bearer $SOLVETHREE_API_KEY"

读取任务状态,而不只是 HTTP 状态

HTTP 成功响应中可能包含仍需轮询的任务。pending 和 solving 是非终态;只有 ready 包含可用的求解结果。failed 是终态,并包含 errorCode 和 error。

任务状态 · 响应结构
{
  "nonterminal": [
    {
      "id": "example-task",
      "status": "pending"
    },
    {
      "id": "example-task",
      "status": "solving"
    }
  ],
  "ready": {
    "id": "example-task",
    "status": "ready",
    "solution": {
      "token": "EXAMPLE_TOKEN",
      "userAgent": "EXAMPLE_USER_AGENT",
      "secChUa": "EXAMPLE_CLIENT_HINTS"
    }
  },
  "failed": {
    "id": "example-task",
    "status": "failed",
    "errorCode": "site-unreachable",
    "error": "target page did not respond"
  }
}

此处展示的就绪响应包含 reCAPTCHA 令牌。Kasada 返回请求头,而 TMPT 返回原始 Cookie 值。结果就绪表示已生成求解结果,不代表下游目标已接受。如果已就绪的 reCAPTCHA 令牌被拒绝,请从轮询诊断转为检查提交的令牌。

超时后恢复现有任务

连接超时表示客户端未收到完整响应,并不能证明创建失败。在付费进行下一次求解前,请先恢复可能已经创建的任务。

  1. 1.

    如果已有任务 ID,请恢复 GET 轮询

    设置一个新的、有时限的本地截止时间,并查询该 ID。GET 超时不是再次提交创建请求的理由。

  2. 2.

    如果创建中断,请复用其 requestId

    使用相同的 requestId 重放完全一致的任务请求,以恢复现有任务。复用该 ID 的同时更改任务输入会产生冲突。完整约定请参阅请求 ID 恢复。

两个 SDK 都会在未提供 requestId 时自动生成,且绝不会自动重试创建。它们的 SolvethreeError 提供恢复所需的 ID:Python 中为 request_id 和 task_id,JavaScript 中为 requestId 和 taskId。决定创建新的逻辑任务之前,请先检查这些字段。

轮询请求返回 HTTP 错误

将 HTTP 状态与任务状态分开检查。SDK 的 ApiError 提供该状态及重试延迟(如有)。

试试这样做: 对于临时轮询失败,请在总体求解时限内遵守 Retry-After。SDK 对应字段为 Python 中以秒为单位的 retry_after,以及 JavaScript 中以毫秒为单位的 retryAfterMs。

任务返回 failed

读取 errorCode 和 error;SDK 将此情况表示为 TaskFailedError。

试试这样做: 停止轮询该任务。创建新任务前,先诊断报告的原因;不要盲目重试未更改的无效输入,也不要认定问题出在余额。

查询返回 HTTP 410

存储的结果已过期。

试试这样做: 不要将其视为临时轮询错误而继续重试查询。已完成结果的保留时间有限,并非永久的求解结果缓存。

保存就绪响应不会延长目标令牌或 Cookie 的有效期。

仍有问题?

请将任务 ID 和收到的错误信息发送给支持团队。

联系支持
处理 CAPTCHA 任务轮询和超时 · solvethree