API Tutorials

如何使用 API 解决 GeeTest v3 问题

用脚本操作带 GeeTest v3 的页面,真正卡住人的往往不是提交请求本身,而是拿不到 gtchallenge 这两个参数——不像 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-slidegettype.phpget.php 过滤
  • 触发一次验证码,找到初始化请求
  • 响应里已经带上 gtchallenge,有时还有 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 识别成功后会返回三个值:challengevalidateseccode

同样两种实现:

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 —— 缺少 gtchallenge,需从页面请求中提取
  • 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,或参考方法三。


相关阅读

  1. GeeTest v3 验证码的识别原理
  2. GeeTest v3 常见报错与修复方法
  3. GeeTest 与 reCAPTCHA 对比
该文章已禁用评论。