用脚本操作带 GeeTest v3 的页面,真正卡住人的往往不是提交请求本身,而是拿不到 gt 和 challenge 这两个参数——不像 reCAPTCHA 的 sitekey,得从网络请求或页面脚本里手动摘出来。
GeeTest(极验)在国内电商、社区、政务类站点的注册登录环节很常见,海外站点也常用它的滑块、图标选择、文字匹配几种挑战形式。
本文按顺序演示:先提取三个关键参数,再交给 CaptchaAI API 提交、轮询,拿到 validate/seccode 后回填目标表单,Python、Node.js 代码可直接套进你现有的 QA 脚本。
准备工作
准备好这几样:
- CaptchaAI API Key —— 在 CaptchaAI 官网 注册后获取
- GeeTest
gt值 —— 站点级静态标识符,同站点通常不变 - GeeTest
challenge—— 每次验证会话都会变化,必须现取现用 - 页面 URL —— 验证码出现页面的完整地址
- 运行环境 —— Python 3.7+ 或 Node.js 14+
第一步:提取 GeeTest v3 验证参数
GeeTest 需要三个参数才能提交给求解服务:
gt静态,同站点基本不变;challenge动态,每次验证都不同。
方法一:抓包分析(Network 面板)
- 打开 DevTools → Network 面板
- 用
register-slide、gettype.php或get.php过滤 - 触发一次验证码,找到初始化请求
- 响应里已经带上
gt、challenge,有时还有api_server
{
"success": 1,
"gt": "019924a82c70bb123aae90d483087f94",
"challenge": "12345678abc90def12345678abc90def",
"new_captcha": true
}
方法二:搜索页面源码
// Search page source for initGeetest or gt value
document.querySelectorAll('script').forEach(s => {
if (s.textContent.includes('initGeetest')) {
console.log(s.textContent);
}
});
方法三:站点自有接口
不少站点是先调用自己的接口拿到 GeeTest 参数,再渲染验证码组件:
# The site's registration endpoint
params_response = requests.get("https://example.com/api/captcha/register")
data = params_response.json()
gt = data["gt"]
challenge = data["challenge"]
第二步:把参数提交给 CaptchaAI API
任选其一:
Python:
import requests
import time
API_KEY = "YOUR_API_KEY"
response = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "geetest",
"gt": "019924a82c70bb123aae90d483087f94",
"challenge": "12345678abc90def12345678abc90def",
"api_server": "api.geetest.com", # Optional, use if site specifies
"pageurl": "https://staging.example.com/qa-login",
"json": 1
})
data = response.json()
if data.get("status") != 1:
raise Exception(f"Submit error: {data.get('request')}")
task_id = data["request"]
print(f"Task submitted: {task_id}")
Node.js:
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
async function submitGeeTest(gt, challenge, pageurl) {
const { data } = await axios.get('https://ocr.captchaai.com/in.php', {
params: {
key: API_KEY,
method: 'geetest',
gt,
challenge,
api_server: 'api.geetest.com',
pageurl,
json: 1
}
});
if (data.status !== 1) throw new Error(`Submit error: ${data.request}`);
return data.request;
}
第三步:轮询获取识别结果
GeeTest 识别成功后会返回三个值:challenge、validate、seccode。
同样两种实现:
Python:
def get_geetest_solution(task_id):
for attempt in range(30):
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 Exception(f"Error: {result.get('request')}")
raise Exception("Timeout")
solution = get_geetest_solution(task_id)
# solution = {
# "geetest_challenge": "12345678abc90def12345678abc90def1a",
# "geetest_validate": "abcdef1234567890abcdef1234567890",
# "geetest_seccode": "abcdef1234567890abcdef1234567890|jordan"
# }
Node.js:
async function getGeeTestSolution(taskId) {
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const { data } = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: API_KEY, action: 'get', id: taskId, json: 1 }
});
if (data.status === 1) return data.request;
if (data.request !== 'CAPCHA_NOT_READY') throw new Error(data.request);
}
throw new Error('Timeout');
}
提示: 轮询间隔 5 秒、最多 30 次是安全上限,正常情况 GeeTest v3 在 12 秒内就有结果。
第四步:把结果提交回目标页面
把三个字段一起发到站点自己的验证接口:
# Submit the GeeTest solution with the form data
verify_response = requests.post("https://example.com/api/login", data={
"username": "[email protected]",
"password": "password123",
"geetest_challenge": solution["geetest_challenge"],
"geetest_validate": solution["geetest_validate"],
"geetest_seccode": solution["geetest_seccode"]
})
print(f"Login status: {verify_response.status_code}")
注册、评论、下单等表单处理方式相同——把三个字段填进原请求即可。
完整 Python 示例
import requests
import time
API_KEY = "YOUR_API_KEY"
SITE_URL = "https://staging.example.com/qa-login"
# 1. Get GeeTest parameters from the site
params = requests.get("https://example.com/api/captcha/register").json()
# 2. Submit to CaptchaAI
submit = requests.get("https://ocr.captchaai.com/in.php", params={
"key": API_KEY,
"method": "geetest",
"gt": params["gt"],
"challenge": params["challenge"],
"pageurl": SITE_URL,
"json": 1
}).json()
task_id = submit["request"]
# 3. Poll for solution
for _ in range(30):
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:
solution = result["request"]
break
# 4. Submit to site
login = requests.post(SITE_URL, data={
"username": "[email protected]",
"password": "pass",
"geetest_challenge": solution["geetest_challenge"],
"geetest_validate": solution["geetest_validate"],
"geetest_seccode": solution["geetest_seccode"]
})
print(f"Result: {login.status_code}")
常见错误与排查
参数问题:
ERROR_BAD_PARAMETERS—— 缺少gt或challenge,需从页面请求中提取ERROR_CAPTCHA_UNSOLVABLE—— 挑战已过期或无效,重新获取一份
结果问题:
- 站点拒绝提交的解题结果 ——
challenge是一次性值,每次提交前都要重新拿一份 geetest_validate返回为空 —— 内部识别失败,换一个新挑战重试
完整可运行示例
需要包含环境配置、轮询、重试和错误处理的完整可运行项目?在 GitHub 上查看完整示例 →
常见问题
GeeTest v4 目前支持吗?
目前不支持,GeeTest v4 协议不同,本文方法只对 v3 有效。
v4 已列为即将支持。
GeeTest v3 识别一般要等多久?
通常 12 秒以内完成,滑块、图标点选、文字匹配几种类型耗时接近。
轮询一直返回 CAPCHA_NOT_READY,什么时候才算超时?
跟示例代码一致:5 秒一次、最多 30 次,约 150 秒未返回就判定超时。通常是 challenge 已失效,重新提取参数再试。
非登录场景(比如注册、评论表单)要怎么提交解题结果?
流程一样,把三个字段填进该表单原本要提交的请求即可。
gt 或 challenge 参数一直提取不到怎么办?
先确认验证码已真正触发过一次,不少站点是懒加载 GeeTest。
仍看不到就改用方法二搜索 initGeetest,或参考方法三。