先说结论:分数低通常不是“被识破了”,而是提交的 token 与页面期望的上下文对不上——action 写错、token 超过两分钟才用、同一会话几秒内连打十几次 grecaptcha.execute()。这三类占了大多数,都不用改浏览器,改调用顺序就行。
安全范围: 本指南仅适用于你自有或经授权的 QA、staging 与预发布环境。内容覆盖针对你自己 CAPTCHA 集成的诊断、测试与可观测性模式 — 不涉及第三方站点或未授权流程。
reCAPTCHA v3 不弹挑战框,只给每次调用打一个 0.0(机器人)到 1.0(真人)的分数,阈值由站点自己设。所以低分永远表现为“静默失败”。
reCAPTCHA v3 的分数由哪些信号决定
Google 打分前采集的特征分这几类。
| 信号类别 | 具体采集什么 |
|---|---|
| 交互行为 | 光标轨迹、滚动与击键节奏 |
| 浏览器特征 | Canvas、WebGL、字体、插件 |
| cookie 与会话 | Google 域下的 cookie 与访问历史 |
| IP 信誉 | 机房 IP 还是家宽 IP、网段记录 |
国内开发者还有个前置坑:reCAPTCHA 的脚本托管在 Google 域名下,大陆网络访问并不稳定——本地调试时脚本没加载出来,那是资源加载失败,不是分数问题。国内站点更多用 GeeTest(极验)、腾讯防水墙、网易易盾,reCAPTCHA v3 主要出现在海外站点上。
七类常见成因,按排查性价比排序
1. action 参数对不上
action 会编码进 token,站点在后端比对。你传 submit、页面实际用 login,分数再高也没用。
处理方式: 在页面源码或 DevTools 里搜 grecaptcha.execute,把 action 原样抄下来。大小写敏感。
2. token 用得太晚
token 有效期是 2 分钟。常见写法是页面一加载就取 token,填完二十个字段才提交,超时就废了。
处理方式: 先填字段,最后取 token 并立即提交。
3. 同一会话请求过密
同一会话短时间内反复调用 grecaptcha.execute(),后续每次分数逐级走低。
处理方式: 间隔至少 15–30 秒;按业务粒度切分会话;QA 场景用队列限流。
4. sitekey 取错了版本
同一域名下可能同时挂着 v2 和 v3 两套 key。典型症状是分数稳定地低,换 IP 换环境都没变化。
处理方式: 确认取的是 render 参数里的 v3 sitekey,提交时 version 写 v3。
5. 机房 IP 与信誉记录
机房 IP 段普遍比家宽 IP 段分数低,被大量脚本用过的公开出口更是如此。
处理方式: 测试流量走自有服务器基础设施,出口稳定可追溯——出口一直在变,分数波动就没法归因。
6. 浏览器信号不完整
默认配置的 headless 浏览器信号残缺:没有鼠标轨迹、没有滚动历史、也没有 cookie。
处理方式: 设置真实的视口尺寸和 User-Agent;让 QA 脚本真实走完流程(滚动、聚焦、正常速度填写);复用持久化的浏览器配置目录。
7. 缺少 Google 会话 cookie
带 Google 账号 cookie(NID、SID、HSID)的浏览器分数通常更高,全新配置起点天然偏低。
处理方式: QA 环境用一个已登录 Google 服务的配置目录,让它持续存在。
一个真实场景:跨境电商的登录回归测试
一家深圳的跨境电商团队,站点在新加坡,登录页阈值 0.5。回归测试本地好好的,一上 CI 就全线失败。
两个问题叠加:CI runner 在机房网络里,IP 信誉本就不占优;更关键的是脚本把并发拉到 20,同一会话十几秒内打了二十次 grecaptcha.execute()——第一个 token 勉强过线,后面十九个全掉到 0.1 以下。
改法很朴素:并发降到 4,每个 worker 独立会话,间隔 20 秒。整轮测试从 3 分钟变成 11 分钟,通过率回到可用水平——v3 上吞吐与分数此消彼长。
用 CaptchaAI 提交 reCAPTCHA v3 任务
CaptchaAI 在真实浏览器环境中处理 reCAPTCHA v3,返回的 token 分数通常在 0.3 附近,能过阈值不高的站点,过不了 0.5 以上的关键页面——分数由 Google 给出。
Python 示例:提交任务后每 5 秒轮询结果。
import requests
import time
response = requests.get("https://ocr.captchaai.com/in.php", params={
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"version": "v3",
"googlekey": "SITE_KEY",
"action": "login",
"pageurl": "https://staging.example.com/qa-login",
"json": 1
})
task_id = response.json()["request"]
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": "YOUR_API_KEY", "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"Token received: {token[:50]}...")
break
Node.js 版本逻辑相同,action 必须与页面里的字符串一致:
const axios = require('axios');
async function solveV3(sitekey, pageurl, action) {
const { data } = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: 'YOUR_API_KEY', method: 'userrecaptcha', version: 'v3',
googlekey: sitekey, action, pageurl, json: 1
}
});
const taskId = data.request;
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const res = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
});
if (res.data.status === 1) return res.data.request;
}
throw new Error('Timeout');
}
拿到 token 后写进页面的 g-recaptcha-response 字段并提交表单。并发取决于线程数:CaptchaAI 按并发线程计费,套餐内识别次数不限。BASIC($15/月,5 线程)够单人调试,ADVANCE($90/月,50 线程)适合持续跑回归测试的团队。任务完成线程即释放。
常见问题
reCAPTCHA v3 要多少分才算通过?
阈值由站点自己定:低风险页面常见 0.3,默认 0.5,支付和账号变更这类关键操作 0.7。这个值从外部读不到,只能靠“哪些分数被接受了”反推。
CaptchaAI 返回的 token 分数大概是多少?
通常在 0.3 左右。分数由 Google 的风险模型给出,识别服务只能把 token 取回来,不能决定它值几分。阈值高于 0.3 的站点,靠识别质量解决不了。
怎么确认目标站点用的是 v3 而不是 v2?
看页面加载的脚本地址:带 render= 参数、且没有可见勾选框的是 v3。同一域名下两套 key 并存很常见,取错版本会表现为分数稳定偏低,换环境也不变。
分数低的时候,为什么后端没有任何报错?
分数由 Google 给出,接受还是拒绝则由站点自己的后端代码决定。多数实现直接返回 200 加一个通用失败态,日志里自然看不到验证码相关的错误。排查要从后端的分数判定逻辑入手。
国内网络环境下怎么测 reCAPTCHA v3?
大陆网络访问 Google 域名不稳定,本地调试容易连基线都跑不出来。可行的做法是把 QA 环境部署在海外节点——这是环境选型问题,本文不涉及任何绕开网络限制的操作。