页面加载 enterprise.js 而不是 api.js?那就是 reCAPTCHA v2 Enterprise —— 解题逻辑和标准 v2 几乎一样,只多加一个参数 enterprise=1。
它通过 Google 的 Enterprise API 校验令牌,而非公开的 siteverify 接口。本文用 Python 和 Node.js 走完检测、提参数、提交、轮询、注入全流程。
国内团队常在这几类场景碰到它:
- 海外 SaaS 后台登录页
- 跨境电商卖家中心
- 面向企业客户的自助门户
不确定是 Enterprise 还是标准版? 先读 如何识别 reCAPTCHA 企业实施。
开始之前,你需要准备什么
- CaptchaAI API Key —— 在 captchaai.com/api.php 领取
- 目标页面 URL —— reCAPTCHA 展示页的完整地址
- sitekey ——
data-sitekey属性 - Enterprise 标识 ——
enterprise.js脚本标签 - data-s 值(如有)—— 部分实现会额外要求
第 1 步:判断页面是不是 Enterprise 版
// Enterprise script tag (NOT api.js)
// <script src="https://www.google.com/recaptcha/enterprise.js?render=SITEKEY"></script>
// Enterprise JavaScript object
// grecaptcha.enterprise.render(...)
// grecaptcha.enterprise.execute(...)
页面源码里搜这两个特征:出现
enterprise.js/grecaptcha.enterprise就是 Enterprise 版,只有api.js/grecaptcha就是标准版。
第 2 步:提取 sitekey 和 data-s
# Sitekey: from data-sitekey attribute
# <div class="g-recaptcha" data-sitekey="6LcR_RsTAAAA..." data-s="..."></div>
# Or from enterprise.js render parameter
# https://www.google.com/recaptcha/enterprise.js?render=6LcR_RsTAAAA...
别漏了
data-s:部分实现把它当额外会话令牌要求。源码搜不到时,去 DevTools 的 Network 面板搜enterprise.js请求即可看到。
第 3 步:提交任务到 CaptchaAI
在标准 v2 的参数基础上加一行 enterprise: 1,其余字段不用变:
import requests
params = {
"key": "YOUR_API_KEY",
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAFJR-JhNbC6CC42wKCbR9Hq_kVCd",
"pageurl": "https://staging.example.com/qa-login",
"enterprise": 1, # Required for Enterprise
"json": 1
}
# Include data-s if present on the page
# params["data-s"] = "data-s-value-from-page"
response = requests.get("https://ocr.captchaai.com/in.php", params=params)
data = response.json()
task_id = data["request"]
print(f"Task ID: {task_id}")
Node.js 版本用 fetch 发起同样的请求:
const params = new URLSearchParams({
key: "YOUR_API_KEY",
method: "userrecaptcha",
googlekey: "6LcR_RsTAAAAAFJR-JhNbC6CC42wKCbR9Hq_kVCd",
pageurl: "https://staging.example.com/qa-login",
enterprise: 1,
json: 1,
});
const res = await fetch(`https://ocr.captchaai.com/in.php?${params}`);
const data = await res.json();
console.log(`Task ID: ${data.request}`);
第 4 步:轮询获取结果
每 5 秒查询一次,最多尝试 40 次(约 200 秒超时):
import time
for _ in range(40):
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: {token[:50]}...")
break
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Error: {result['request']}")
Node.js 逻辑相同:
let token;
for (let i = 0; i < 40; i++) {
await new Promise((r) => setTimeout(r, 5000));
const res = await fetch(
`https://ocr.captchaai.com/res.php?${new URLSearchParams({
key: "YOUR_API_KEY", action: "get", id: taskId, json: 1,
})}`
);
const data = await res.json();
if (data.status === 1) { token = data.request; break; }
if (data.request !== "CAPCHA_NOT_READY") throw new Error(data.request);
}
第 5 步:把 token 注入页面
注入方式和标准 v2 完全一致:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://staging.example.com/qa-login")
# Inject token into hidden field
driver.execute_script(
f'document.getElementById("g-recaptcha-response").innerHTML = "{token}";'
)
# Check for callback
callback = driver.execute_script(
'var el = document.querySelector(".g-recaptcha"); '
'return el ? el.getAttribute("data-callback") : null;'
)
if callback:
driver.execute_script(f'{callback}("{token}");')
else:
driver.find_element("css selector", "form").submit()
没跳转就先查 g-recaptcha-response 里有没有值,别急着重新提交任务。
完整的工作示例
import requests
import time
def solve_recaptcha_v2_enterprise(api_key, sitekey, page_url, data_s=None):
params = {
"key": api_key, "method": "userrecaptcha",
"googlekey": sitekey, "pageurl": page_url,
"enterprise": 1, "json": 1
}
if data_s:
params["data-s"] = data_s
submit = requests.get("https://ocr.captchaai.com/in.php", params=params).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
for _ in range(40):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": api_key, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"]
if result.get("request") != "CAPCHA_NOT_READY":
raise RuntimeError(f"Solve error: {result.get('request')}")
raise TimeoutError("Solve timed out after 200s")
# Usage
token = solve_recaptcha_v2_enterprise("YOUR_API_KEY", "6LcR_RsTAAAA...", "https://staging.example.com/qa-login")
print(f"Solved: {token[:50]}...")
完整可运行的项目示例
想直接跑起来?仓库里的示例项目包含:
- 环境变量读取
- 提交、轮询、重试逻辑
- 超时和错误处理
常见问题
下面是集成时最常被问到的几个问题。
什么情况下必须传 data-s 参数?
只有当 reCAPTCHA 容器带了 data-s 属性才需要提交。大多数 Enterprise 实现不用它,源码里搜一下,没有就跳过。
如何确认提取到的 sitekey 是对的?
只能从当前页面拿——data-sitekey 属性或 enterprise.js 的 render 参数。Enterprise 页面和标准版 sitekey 常不一样,别照搬旧文档。
国内团队测试海外站点的 Enterprise reCAPTCHA,要注意什么?
reCAPTCHA 依赖 Google 托管的脚本,从中国大陆网络直接访问常有加载慢、超时的情况,容易被误判成接口异常,其实是网络可达性问题。建议在能稳定访问 Google 服务的环境里联调。
token 提交后网站还是拦截我,可能是什么原因?
- 请求是否带了
enterprise=1 - sitekey 是否和目标页面一致
- 页面有
data-s时是否一并提交 - token 是否在 2 分钟内完成注入
基本是这四个原因之一。
现在就开始处理 reCAPTCHA v2 Enterprise
拿到 API Key:captchaai.com/api.php,在现有标准 v2 代码里加一个 enterprise=1 参数即可。
按线程计费,最新套餐和价格见 CaptchaAI 官网。
相关指南
- 如何识别 reCAPTCHA 企业实施
- 常见 reCAPTCHA v2 Enterprise 错误排查
- 如何使用 API 解决 reCAPTCHA v2
- 标准版与 Enterprise 版 reCAPTCHA v2 对比