在 Python 和 Node.js 中求解多个 CAPTCHA
限制正在进行的解题任务数量,而不只是发起的请求数量。以下示例运行八个独立的 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 和完全相同的输入。
运行有界批处理
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__)import { randomUUID } from 'node:crypto';
import { Solvethree } from '@solvethree/sdk';
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const jobs = Array.from({ length: 8 }, () => ({
site: 'accounts.example.com', action: 'login',
proxy: process.env.SOLVETHREE_PROXY, requestId: randomUUID(),
}));
let next = 0;
async function worker() {
while (next < jobs.length) {
const job = jobs[next++];
try {
const result = await client.solve(job, { timeoutMs: 180_000 });
console.log('Ready task:', result.id);
// Submit this solution promptly, before taking another job.
} catch (error) {
console.error('One task failed:', error.constructor.name);
}
}
}
await Promise.all(Array.from({ length: Math.min(4, jobs.length) }, worker));这里 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 都不会自动重试任务创建,因此请保留足够的信息,以便仅恢复被中断的作业,而不是重新提交已成功的任务。
来源与 API 参考
运行您的第一个任务。
使用 $5 工作区额度开始体验。