使用 Node.js 求解 reCAPTCHA Enterprise

作者:solvethree阅读需 1 分钟

在 Node.js 22+ 上使用官方 solvethree JavaScript SDK。配置已启用的站点配置文件,提供站点的主机名和操作,并通过代理进行求解。SDK 会返回令牌和浏览器身份;你的应用负责将它们提交到目标站点。

本页内容

安装 SDK 并配置站点

直接从 solvethree.com 安装官方软件包:

安装 Node.js SDK
npm install https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgz
  1. 1.

    启用站点配置文件

    在控制台中设置目标站点,并确保其配置文件已启用且可供你的工作区使用。发送主机名和操作不会创建配置文件。请参阅站点配置文件设置。

  2. 2.

    设置服务器环境

    在 Node.js 进程的环境中,将 SOLVETHREE_API_KEY 设置为你的工作区 API 密钥,将 SOLVETHREE_PROXY 设置为你的代理 URL。将 API 密钥保存在服务器端;不要在浏览器代码中暴露它。

  3. 3.

    准备脚本

    将下一个示例保存为 solve.mjs。将 accounts.example.com 替换为你已配置的主机名,将 login 替换为页面实际使用的 reCAPTCHA 操作。

请求 Enterprise 令牌

site 应使用主机名,而不是页面 URL。reCAPTCHA 默认为 enterprise-v3,因此此示例不需要 recaptchaType。不要添加 type 或 url。请求必须提供 proxy 或 proxyCandidates,且只能二选一;此示例使用单个代理。

Node.js · solve.mjs
import { randomUUID } from 'node:crypto';
import { Solvethree, SolvethreeError, TaskFailedError } from '@solvethree/sdk';

const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const request = {
  site: 'accounts.example.com', // Use your configured hostname.
  action: 'login',              // Use the page's actual action.
  proxy: process.env.SOLVETHREE_PROXY,
  requestId: randomUUID(),
};
let result;
try {
  result = await client.solve(request, { timeoutMs: 180_000 });
} catch (error) {
  if (error instanceof TaskFailedError) {
    throw new Error(`Task failed: ${error.errorCode}`);
  }
  if (error instanceof SolvethreeError) {
    // Save these IDs; use them to recover the existing task.
    console.error({ requestId: error.requestId, taskId: error.taskId });
  }
  throw error;
}
const { token, userAgent, secChUa } = result.solution;
console.log('Ready task:', result.id); // Keep solution credentials private.

设置环境变量后,使用 Node.js 运行脚本。solve 只创建一次任务,并持续轮询,直到任务就绪或抛出异常。180,000 毫秒的超时限制了客户端的等待时间。

返回的各字段用途不同:

  • result.id 用于标识任务。它不是 CAPTCHA 令牌。
  • result.solution.token 是应提交到应用 CAPTCHA 字段的值。
  • result.solution.userAgent 和 result.solution.secChUa 是应与该令牌配合使用的浏览器身份。

请勿泄露解决方案中的值。如果需要在进程重启后恢复,请在调用 solve 前保存 requestId 和完整的原始任务输入,并保护好其中的代理凭据。

通过同一个代理提交

在 solve 返回后,在同一个脚本中继续执行。此示例使用 undici,你必须按照注释说明单独安装它。示例通过 request.proxy 发送令牌,并使用返回的两个浏览器身份字段。

Node.js undici · 应用已就绪的解决结果
// Continue after client.solve(). Install undici separately: npm install undici@7.
import { fetch, ProxyAgent } from 'undici';

const dispatcher = new ProxyAgent(request.proxy);
try {
  // Replace the URL and form fields with your application's contract.
  const response = await fetch('https://accounts.example.com/login', {
    method: 'POST',
    dispatcher,
    redirect: 'manual',
    headers: {
      'user-agent': result.solution.userAgent,
      'sec-ch-ua': result.solution.secChUa,
    },
    body: new URLSearchParams({
      'g-recaptcha-response': result.solution.token,
    }),
    signal: AbortSignal.timeout(30_000),
  });
  console.log('Application HTTP status:', response.status);
  await response.arrayBuffer();
} finally {
  await dispatcher.close();
}

根据应用的接口约定替换 URL 和表单字段。此示例仅提供 g-recaptcha-response;请添加应用所需的其他字段和会话数据。确保目标与求解时使用的站点和操作一致。

由于求解请求使用单个代理,复用 request.proxy 可确保通过该代理提交。如果将请求改为使用 proxyCandidates,则应改用 SDK 的 successfulProxy 辅助函数选择求解成功所用的代理。

任务就绪表示已生成解决方案,并不表示目标站点已接受你的应用请求。请检查目标站点的响应,确认是否满足其实际成功条件;仅输出 HTTP 状态还不够。如需诊断拒绝原因,请参阅就绪令牌被拒绝。

处理失败并恢复中断的请求

求解示例将终态任务失败与其他 SDK 错误分开处理。请保留这一区分:任务失败和 HTTP 请求失败需要不同的处理方式。

solve 抛出 TaskFailedError

异常包含 errorCode 和 taskId。如果需要完整的失败任务响应(包括错误文本),请调用 getTask(taskId)。

试试这样做: 停止轮询该任务,并在创建新任务之前解决报告的问题。不要使用未作更改的无效输入重试。

SolvethreeError 包含 taskId

SDK 已获得现有任务的 ID。

试试这样做: 使用 getTask 恢复轮询。状态为 pending 或 solving 时继续轮询,仅在 ready 时使用解决方案,在 failed 时停止。

创建过程被中断,且只有 requestId 可用

连接超时并不能证明任务未创建。

试试这样做: 使用完全相同的任务输入和同一个 requestId 调用 createTask 进行恢复。使用不同的输入复用该 ID 会产生冲突。

API 拒绝 HTTP 请求

检查 ApiError 提供的 HTTP 状态,而不是将响应视为就绪或失败的任务。

试试这样做: 先解决 HTTP 错误,再处理成功响应载荷。不要假定所有失败都是余额不足。

此示例在每次程序启动时都会生成新的 requestId。原样重新运行并不等于恢复:应使用已保存的请求和 ID。SDK 从不自动重试创建任务;对于临时轮询失败,它会在求解截止时间内遵循 Retry-After。

有关显式轮询和等待设置,请参阅任务轮询与超时。

运行您的第一个任务。

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

创建工作区
使用 Node.js 求解 reCAPTCHA Enterprise · solvethree