在 Python 和 Node.js 中求解多个 CAPTCHA

作者:solvethree阅读需 1 分钟

限制正在进行的解题任务数量,而不只是发起的请求数量。以下示例运行八个独立的 reCAPTCHA Enterprise 任务,同时最多进行四个解题任务,并在每个结果完成时立即处理。

四只是示例并发设置,并非 solvethree 的容量限制。请根据应用使用返回结果的速度选择合适的上限。

本页内容

准备 SDK 和任务输入

使用 Python 3.10+ 或 Node.js 22+。通过文档中的下载 URL 安装官方 SDK;请直接下载软件包。将工作区 API 密钥保存在服务器端。

  • 在服务器环境中设置 SOLVETHREE_API_KEY 和 SOLVETHREE_PROXY。
  • 将 accounts.example.com 和 login 替换为目标主机名和 action。该站点必须已有已激活且可供你的工作区使用的配置;提交主机名不会创建配置。
  • 将 jobs 中的每个条目视为独立的逻辑任务。为便于阅读,示例重复使用相同的站点、action 和代理,但为每个任务分配不同的 requestId。
  • 恢复期间,请保持每个任务的输入不变。新的独立解题任务需要新的 ID;恢复被中断的解题任务则需要原始 ID 和完全相同的输入。

运行有界批处理

Python · 同时执行四次求解
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from uuid import uuid4
from solvethree import Solvethree

# Each worker gets its own synchronous client.
def solve_one(job):
    client = Solvethree(os.environ["SOLVETHREE_API_KEY"])
    return client.solve({**job, "requestId": str(uuid4())}, timeout=180)

jobs = [
    {"site": "accounts.example.com", "action": "login", "proxy": os.environ["SOLVETHREE_PROXY"]}
    for _ in range(8)
]
with ThreadPoolExecutor(max_workers=4) as pool:
    futures = [pool.submit(solve_one, job) for job in jobs]
    for future in as_completed(futures):
        try:
            result = future.result()
            print("Ready task:", result["id"])
            # Submit this solution promptly; don't wait for the whole batch.
        except Exception as error:
            print("One task failed:", type(error).__name__)

这里 Python 需要使用线程,因为 `Solvethree` 是同步的。 每次 solve 调用都会创建任务,然后等待结果就绪或抛出异常。由于没有原生异步客户端,直接在异步函数中调用它仍会阻塞该函数所在的事件循环线程。示例使用四个线程池工作线程,每个线程都有自己的客户端,并在 future 完成时立即处理,无需等待整个批次。

Node.js 通过四个工作 Promise 限制并发。 每个工作单元都会等待一次解题完成后再领取另一个作业。Promise.all 等待的是这些工作单元,并不会一次启动所有作业。相比之下,将不受限的作业列表直接映射为 solve 调用会立即启动整个列表,无法有效限制并发。

两个示例都会按任务捕获错误,因此一个解题任务失败不会阻止其余作业。180 秒超时适用于每次 solve 调用,而非整个批次。

立即使用每个已就绪的结果

运行实际批处理前,请将成功路径中的注释替换为向目标提交结果的代码。打印的 ID 用于标识任务,并非 reCAPTCHA 令牌。请使用为该任务提供的同一代理,将 solution.token 与返回的 userAgent 和 secChUa 一起提交。

不要收集所有令牌后再等最慢的解题任务完成才开始使用。每个结果就绪后,应在收到的位置立即处理。SDK 负责解答验证码,不会将解决结果提交到目标网站;任务已就绪也不能证明目标网站接受了后续请求。

仅恢复被中断的任务,而非整个批次

为使工作单元模式保持简洁,示例只打印错误类名。在实际集成中,请保留受影响的作业及 SDK 错误提供的恢复 ID:Python 使用 request_id 和 task_id;JavaScript 使用 requestId 和 taskId。

解题超时或连接中断。

检查错误中是否包含任务 ID 或请求 ID。远程任务可能仍然存在。

试试这样做: 如果知道任务 ID,请恢复 GET 轮询。否则,使用相同的请求 ID 和完全相同的输入重放请求,以恢复创建过程。

SDK 抛出 TaskFailedError。

检查已进入终态的任务的 errorCode 和 error。

试试这样做: 停止轮询该任务,并在开始另一次解题前解决报告的原因。不要盲目重试未经修改的无效输入。

重新运行任一示例都会生成新的请求 ID 并启动新的逻辑任务,这不是恢复。两个 SDK 都不会自动重试任务创建,因此请保留足够的信息,以便仅恢复被中断的作业,而不是重新提交已成功的任务。

运行您的第一个任务。

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

创建工作区
在 Python 和 Node.js 中求解多个 CAPTCHA · solvethree