在 Puppeteer 中使用 CAPTCHA 求解服务
使用官方 JavaScript SDK 获取 reCAPTCHA v3 Enterprise 令牌,再通过 Puppeteer 将 solution.token 传递给表单。SDK 负责求解任务,不会将解答应用到浏览器,也不提供浏览器插件。
以下示例针对您拥有的 HTTPS 表单,其中包含 g-recaptcha-response 文本区域和提交按钮。这些是演示表单的要求,并非适用于所有受 reCAPTCHA 保护页面的通用接口。
本页内容
准备依赖和自有表单
- 1.
安装 Puppeteer 和 SDK
使用 Node.js 22 或更高版本。通过 npm 安装
puppeteer,并从https://solvethree.com/downloads/solvethree-sdk-0.1.0.tgz安装官方 SDK tarball 包。SDK 的导入名称为@solvethree/sdk;请使用下载 URL,不要假定它已在 npm 注册表中发布。将示例保存为 ES 模块,例如以.mjs结尾的文件。 - 2.
配置站点配置文件
在 solvethree 控制台中设置您拥有的主机名,并确保其配置已在您的工作区启用。发送主机名和操作不会创建该配置。示例使用操作
login;请将其改为您的应用所配置的操作。 - 3.
设置环境变量
将
TARGET_URL设置为您拥有的 HTTPS 表单地址,将SOLVETHREE_PROXY设置为 HTTP 或 HTTPS 代理 URL,将SOLVETHREE_API_KEY设置为工作区密钥。将密钥保留在 Node.js 进程中,不要放入页面 JavaScript。示例在求解和浏览器提交时使用同一个代理。
任务的 site 是从 TARGET_URL 提取的主机名,而不是完整页面 URL。对于 reCAPTCHA,请发送 site、action,以及 proxy 或 proxyCandidates 中的且仅其中一个;不要添加 type 或 url 字段。此示例使用 proxy,以便 Puppeteer 直接使用同一个代理。
先求解,再以相同身份启动 Puppeteer
// Install puppeteer and the official solvethree SDK first.
import puppeteer from 'puppeteer';
import { Solvethree } from '@solvethree/sdk';
const target = new URL(process.env.TARGET_URL); // Your configured HTTPS page.
const proxy = new URL(process.env.SOLVETHREE_PROXY);
const client = new Solvethree({ apiKey: process.env.SOLVETHREE_API_KEY });
const result = await client.solve({
site: target.hostname, action: 'login', proxy: process.env.SOLVETHREE_PROXY,
});
const browser = await puppeteer.launch({
args: [`--proxy-server=${proxy.protocol}//${proxy.host}`],
});
try {
const page = await browser.newPage();
if (proxy.username) await page.authenticate({
username: decodeURIComponent(proxy.username),
password: decodeURIComponent(proxy.password),
});
await page.setUserAgent({ userAgent: result.solution.userAgent });
await page.setExtraHTTPHeaders({ 'sec-ch-ua': result.solution.secChUa });
await page.goto(target.href);
// Adapt these selectors and any required callback to your own form.
await page.waitForSelector('[name="g-recaptcha-response"]');
await page.$eval('[name="g-recaptcha-response"]', (field, token) => {
field.value = token;
field.dispatchEvent(new Event('input', { bubbles: true }));
}, result.solution.token);
await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('button[type="submit"]'),
]);
// Check your application's success response here.
} finally {
await browser.close();
}client.solve 只创建一次任务,并持续轮询,直到任务就绪或抛出异常。此示例仅在该调用返回后启动 Puppeteer。浏览器使用任务的代理,在代理包含凭据时进行身份验证,并在导航前应用 solution.userAgent 和 solution.secChUa。
提交令牌时,不要将该代理或浏览器身份信息替换为无关值。如果之后改用 proxyCandidates,请使用 SDK 的 successfulProxy 辅助函数,为浏览器选出成功完成求解的原始代理。
如果求解失败,请检查任务的 errorCode 和 error,不要使用未经修改的输入重试。HTTP 请求错误与任务终态失败是不同的情况。finally 块会在浏览器操作结束后关闭本地浏览器;关闭页面并不是取消远程任务的机制。
替换演示中的表单假设
[name="g-recaptcha-response"]用于选择演示文本区域。如果您的应用通过其他字段或请求参数接收令牌,请替换它。应提交的值是solution.token,而不是任务 ID。button[type="submit"]用于选择演示的提交按钮。请使用应用实际的控件或提交机制。- 示例会赋予令牌值并派发
input事件。这不能替代应用特定的回调。请在提交前添加所需的回调、CSRF 值、登录字段和会话设置。 - 将最后的成功检查注释替换为针对应用响应或结果状态的断言。求解任务就绪并不能证明应用已接受令牌。
如果复用正在运行的浏览器,请有意识地选择其 BrowserContext:新页面并不自动意味着独立会话。请统一处理表单的会话要求,不要混用来自无关工作流程的页面。
来源与 API 参考
运行您的第一个任务。
使用 $5 工作区额度开始体验。