reCAPTCHA v3 评分机制如何工作
reCAPTCHA v3 是 Google 于 2018 年推出的隐形人机验证系统,其核心是 reCAPTCHA v3 score——一个介于 0.0 与 1.0 之间的连续风险评分,由前端 grecaptcha.execute() 在每次用户动作时生成,并由后端通过 siteverify 校验。与 v2 的“点击复选框”或“选图片”不同,v3 不向终端用户展示任何挑战,而是把判别压力转移给站点开发者:你需要在服务端设定阈值,决定 0.3 以下的请求直接拦截,0.3-0.6 之间触发二次挑战(如邮件验证、v2 回退),0.6 以上放行。理解 how recaptcha v3 works,本质上是理解一个多信号融合的在线风险模型,而非一个简单的“是否机器人”开关。
对 QA 自动化工程师与反爬研究者而言,v3 的难点在于:评分不是单一维度,而是 行为遥测 × 浏览器一致性 × IP 信誉 × Google 账户图谱 的加权融合。任何一个维度异常都会把整体分数压到阈值以下,即使其他维度看起来完全正常。这也是为什么单纯“模拟鼠标移动”或“加随机延迟”往往无法把 recaptcha score 0.3 拉回到 0.7 以上——IP 信誉和浏览器指纹的权重在 2024-2026 间显著提升。
一、评分模型:0.0-1.0 的连续风险分
1.1 score 的生成与 eleven score buckets
调用 grecaptcha.execute(siteKey, {action: 'login'}) 后,前端会拿到一个一次性 token,该 token 在 siteverify 时被 Google 后端解码为结构化响应,其中 score 字段就是最终的风险评分。Google 官方文档没有公开精确的分桶边界,但根据 Google reCAPTCHA v3 开发者文档 与多家站点实测,分数被离散化为 11 个桶:0.0, 0.1, 0.2, …, 1.0,步长 0.1。也就是说,你几乎不会看到 0.47 这样的分数,只会看到 0.4 或 0.5。
典型站点阈值(来自公开部署案例与社区经验):
| 分数区间 | 典型处置 | 常见场景 |
|---|---|---|
| 0.0 - 0.2 | 直接拦截 / 静默丢弃 | 注册、支付、批量提交 |
| 0.3 - 0.5 | 触发二次验证(邮件/SMS/v2 回退) | 登录、密码重置 |
| 0.6 - 0.7 | 放行但记录风控日志 | 搜索、内容浏览 |
| 0.8 - 1.0 | 放行 | 已登录高信誉账户 |
需要强调:0.6 不是“人类”的硬边界。Google 建议站点结合 action 与历史基线动态调整阈值。例如,一个金融类站点可能把登录阈值设到 0.7,而内容站可能把评论阈值设到 0.4。
1.2 score 是 per-action 的,不是 per-session 的
每次 execute 都会生成一个独立 token 与独立 score,且 action 字符串必须与后端期望一致。如果前端用 action: 'login' 拿到 token,后端 siteverify 返回的 action 不是 login,Google 官方明确要求拒绝该请求,否则攻击者可以用首页拿到的 token 去提交支付表单,绕过动作绑定。这是 how recaptcha v3 works 中最常被忽视的一点。
二、Google 融合的信号集合
v3 的评分引擎是一个黑盒,但通过 Google 的公开描述与多方逆向观察,可以归纳出以下信号族:
2.1 行为遥测(behavioral telemetry)
- 鼠标轨迹:移动速度、加速度、曲率、停顿点。线性匀速移动会被判为机器。
- 滚动:scroll 事件的节奏、是否到达页面底部、是否在表单上方停留。
- 键盘:keydown/keyup 间隔、退格频率、复制粘贴事件。
- 页面交互:focus/blur、点击坐标相对元素中心的偏移、页面停留时长。
这些信号在 reCAPTCHA 的 JS 脚本中被采集并加密回传,Google 用其训练的分类器给出一个“行为像不像人”的子分数。问题是:现代浏览器自动化框架(Puppeteer、Playwright)默认不产生这些事件,或产生的事件分布与真实人类差异显著。
2.2 浏览器与设备指纹
Google 不像指纹识别厂商那样公开罗列指纹项,但其脚本会采集:
- UA 与 navigator 属性:platform、languages、hardwareConcurrency、deviceMemory、maxTouchPoints。
- Canvas 与 WebGL 渲染指纹:渲染特定图形后读取像素,不同 GPU/驱动会产生细微差异。
- TLS 指纹(JA3/JA4):ClientHello 中的 cipher suite 顺序、扩展列表、椭圆曲线。Chrome、Firefox、curl、Python requests 各有不同的 JA3。Google 的边缘可以在 TLS 层就识别出“这个 ClientHello 不像 Chrome”。
- 音频指纹:AudioContext 渲染特定波形后的输出差异。
对自动化来说,这意味着即使你把 UA 改成 Chrome,只要 TLS 指纹是 Python requests 的(典型 JA3 如 771,4865-4866-4867-49195-49199-...),Google 在握手阶段就能把这条连接标记为可疑。要“干净地通过”,必须使用真实浏览器内核,而非 requests 或 httpx 直接发请求。
2.3 Google Cookie 图谱
这是 v3 相对 v2 最显著的升级。如果浏览器中存在 Google 的登录态 cookie(__Secure-3PSID 等)或 NID 广告 cookie,Google 可以把当前会话与一个长期账户信誉关联。一个有十年历史、日常正常使用 Gmail 的账户,其关联流量几乎总是拿到 0.8+ 的分数;一个全新无 cookie 的环境,即使行为完美,也常常只有 0.5-0.6。
这一信号对自动化是双刃剑:合法的 QA 测试可以用真实账户登录态获得高分,但任何试图大规模伪造账户的滥用都会因为 cookie 图谱缺失而迅速暴露。
2.4 IP 信誉
这是 recaptcha v3 bypass 讨论中最关键也最被低估的一环。Google 维护一个 IP 信誉库,数据来源包括:
- 已知数据中心 ASN(AWS、GCP、Azure、OVH、Hetzner 等)。
- 历史滥用记录(同一 IP 上是否出现过 v2 失败、大规模请求)。
- Tor exit node、公开代理列表、VPN 提供商 IP 段。
- residential IP 的地理一致性(IP 归属国与浏览器 locale/时区是否匹配)。
实测中,一个来自 AWS us-east-1 的 IP,即使浏览器指纹与行为都完美,score 通常也只能到 0.1-0.3;而同一套浏览器环境切换到美国住宅 IP,score 可以立即跳到 0.7-0.9。这就是为什么 住宅代理是合法通过 v3 的必要条件,而非可选优化。
三、为什么数据中心 IP 会让分数坍塌
把上述信号组合起来看,v3 的评分可以粗略理解为:
score = f(behavior, browser_fp, google_cookie, ip_reputation)
其中 ip_reputation 是一个“乘性”因子:如果 IP 被标记为数据中心或高风险,无论其他信号多强,最终分数都会被压到一个上限(经验上约 0.3-0.4)。这解释了一个常见困惑:“我把鼠标轨迹模拟得非常像人,为什么还是 0.2?”——因为你的 IP 是 AWS,行为信号的提升被 IP 信誉的乘性惩罚吃掉了。
更具体地,数据中心 IP 在 v3 中面临三重劣势:
- ASN 黑名单:Google 长期维护数据中心 ASN 列表,这些段的流量默认进入“高风险先验”。
- 共享滥用历史:云厂商的 IP 池高度复用,你今天拿到的 IP,昨天可能被某个爬虫用过并已被标记。
- 地理不一致:数据中心 IP 的 GeoIP 往往与实际物理位置有偏差,而 v3 会校验 IP 国家与浏览器 timezone/locale 的一致性。
因此,对于任何需要在 v3 保护下进行合法自动化(QA 回归、可访问性测试、授权安全测试)的场景,住宅代理不是“绕过”,而是“让 IP 信誉信号回到正常基线”。这与 Google reCAPTCHA FAQ 中“不要使用数据中心代理进行自动化测试”的隐含建议一致。
四、服务端验证:siteverify 的三个必检项
前端拿到 token 后,后端必须 POST 到 https://www.google.com/recaptcha/api/siteverify,参数包括 secret、response(token)、可选的 remoteip 与 action。返回的 JSON 包含:
{
"success": true,
"score": 0.7,
"action": "login",
"challenge_ts": "2026-01-15T10:23:45Z",
"hostname": "example.com",
"error-codes": []
}后端必须做三项校验,缺一不可:
- success === true:token 有效且未过期(token 有效期约 2 分钟)。
- action 匹配:返回的
action必须等于你期望的动作名。不匹配则拒绝,防止 token 跨动作复用。 - hostname 匹配:返回的
hostname必须是你的域名,防止 token 被从其他站点窃取后重放。
很多站点只检查 success 与 score,忽略 action/hostname,这是 v3 部署中最常见的安全漏洞。对自动化测试者来说,理解这套校验有助于定位“为什么我的 token 被拒”——往往是 action 拼写不一致或 hostname 与请求来源不符。
五、合法自动化实践:ProxyHat 住宅代理 + 真实浏览器
以下示例面向授权的 QA 回归与可访问性自动化——即你拥有目标站点或获得书面测试授权。它不适用于绕过他人站点的反爬机制,也不适用于账户注册滥用或欺诈。
5.1 架构
- 浏览器:Playwright + Chromium,启用 stealth 插件以修补
navigator.webdriver、Chrome runtime 属性等已知泄漏点。 - 代理:ProxyHat 住宅代理,通过
gate.proxyhat.com:8080接入,用户名中带-country-US以保证 IP 地理与浏览器 timezone 一致。 - 行为:模拟真实人类节奏的鼠标移动、滚动与输入间隔,避免匀速线性轨迹。
5.2 可运行示例
from playwright.sync_api import sync_playwright
PROXY = "http://user-country-US:pass@gate.proxyhat.com:8080"
def human_like_browse(page, url):
# 先滚动浏览页面,产生真实交互遥测
page.goto(url, wait_until="networkidle")
for _ in range(3):
page.mouse.move(400 + _*80, 300 + _*20, steps=15)
page.wait_for_timeout(800 + _*300)
page.evaluate("window.scrollBy(0, 600)")
page.wait_for_timeout(1200)
def get_recaptcha_score(page):
# 执行 reCAPTCHA v3,action 需与站点期望一致
token = page.evaluate('''() => {
return new Promise((resolve) => {
grecaptcha.execute('YOUR_SITE_KEY', {action: 'login'})
.then(token => resolve(token));
});
}''')
return token
with sync_playwright() as p:
browser = p.chromium.launch(
headless=False,
proxy={"server": PROXY}
)
context = browser.new_context(
locale="en-US",
timezone_id="America/New_York",
viewport={"width": 1366, "height": 768}
)
page = context.new_page()
human_like_browse(page, "https://your-authorized-site.com/login")
token = get_recaptcha_score(page)
print("Token:", token[:40], "...")
# 后端 siteverify 校验由你的服务端完成
browser.close()关键点:
locale与timezone_id必须与代理 IP 的国家一致。美国住宅 IP 配 Asia/Shanghai 时区是典型的“地理不一致”信号。headless=False不是必须,但 headless 模式下某些 canvas/audio 指纹会与有头模式不同,建议测试时先用有头模式建立基线。- 行为模拟的节奏分布比绝对值更重要:真实人类的鼠标停顿服从长尾分布,而非均匀分布。
5.3 SOCKS5 变体
如果你的浏览器栈更偏好 SOCKS5,ProxyHat 同样支持:
socks5://user-country-US:pass@gate.proxyhat.com:1080在 Playwright 中把 proxy.server 改为 socks5://user-country-US:pass@gate.proxyhat.com:1080 即可。SOCKS5 不经过 HTTP CONNECT 隧道,对某些 WebSocket/SSE 场景兼容性更好。
六、常见错误与边界情况
6.1 只换 IP 不换浏览器指纹
这是最常见的失败模式。开发者把 requests 换成住宅代理,但仍然用 requests.get() 直接请求 reCAPTCHA 端点。结果:IP 信誉好了,但 TLS 指纹(JA3)是 Python 的、没有 JS 执行环境、没有 cookie——score 依然在 0.1-0.2。住宅代理必须配合真实浏览器内核才有意义。
6.2 token 跨动作复用
用 action: 'homepage' 拿到的 token 去提交 action: 'payment' 的表单。后端如果正确校验 action,会直接拒绝;如果后端没校验,那是后端的漏洞,不应依赖它。
6.3 score 抖动与时间窗口
同一环境连续调用 execute,score 可能在 0.6-0.9 之间抖动。这是因为 Google 的模型会考虑请求频率——短时间内同一 IP+浏览器的大量 execute 调用本身就是一个异常信号。建议每次动作之间留足真实交互间隔。
6.4 recaptcha score 0.3 的诊断
如果你的 score 卡在 0.3 附近,按以下顺序排查:
- IP 是否为数据中心?换住宅代理(如 ProxyHat 覆盖地点)。
- 浏览器是否为真实内核?
navigator.webdriver是否为 true? - locale/timezone 是否与 IP 国家一致?
- 是否有 Google cookie 登录态?无 cookie 环境天然偏低。
- 行为是否有真实交互?纯
goto后立即execute几乎必低。
七、适用边界与合规
本文方法仅适用于:
- 你拥有目标站点的授权 QA 与回归测试。
- 可访问性自动化测试(如屏幕阅读器兼容性回归)。
- 获得书面授权的安全渗透测试。
- 学术性反爬研究,且不针对生产环境造成实际负载。
不适用于:绕过他人站点的反爬、批量账户注册、票务抢购、信用卡测试、评论垃圾信息。在美国,未经授权访问受保护系统可能违反 CFAA(计算机欺诈与滥用法);在欧盟,大规模自动化处理个人数据可能触发 GDPR。即使技术上可行,也并不意味着法律上允许。
对 ProxyHat 用户而言,住宅代理的正当价值在于让合法自动化回到与真实用户相同的 IP 信誉基线,而非帮助绕过站点明确设置的访问控制。更多合规用例见 网页抓取用例 与 SERP 跟踪用例。
关键要点
- reCAPTCHA v3 score 是多信号融合的连续评分,IP 信誉是乘性因子,数据中心 IP 会把分数压到 0.3 以下。
- 住宅代理 + 真实浏览器内核是通过 v3 的必要组合,缺一不可。
- 后端必须校验 action 与 hostname,否则 token 可被跨动作重放。
- score 抖动正常,短时间高频
execute本身是异常信号。 - 合规优先:仅在授权测试与可访问性自动化中使用,避免 CFAA/GDPR 风险。
如果你准备在自己的授权环境中实测,可以从 ProxyHat 定价 选择住宅代理套餐,或参考 ProxyHat 文档 了解用户名参数与城市级定位的完整用法。






