Hướng Dẫn API

Cách giải quyết GeeTest v3 bằng API

GeeTest v3 không phải captcha ảnh tĩnh: người dùng phải kéo mảnh ghép, chọn đúng icon hoặc ghép từ, và mỗi lần trang tải lại hệ thống sinh ra một challenge mới. Muốn giải bằng API, bạn phải trích xuất ba tham số (gt, challenge, api_server) trực tiếp từ trang web trước khi gửi — đây là điểm khác biệt lớn nhất so với reCAPTCHA, vốn chỉ cần sitekey.

Bài viết đi thẳng vào quy trình 4 bước: trích xuất tham số → gửi task → polling res.php → dùng kết quả, kèm code Python và Node.js chạy được ngay. Đây cũng là luồng nhiều đội QA outsourcing ở TP.HCM và Hà Nội dùng để kiểm thử form đăng nhập, checkout trên staging của ứng dụng thương mại điện tử gắn GeeTest v3, trước khi đưa build lên production.


Yêu cầu

Trước khi bắt đầu, bạn cần:

  • API key CaptchaAI — lấy tại captchaai.com
  • Giá trị GeeTest gt — định danh tĩnh, cố định theo từng trang web
  • GeeTest challenge — giá trị động, đổi theo mỗi phiên
  • URL trang nơi GeeTest hiển thị
  • Python 3.7+ hoặc Node.js 14+

Bước 1: trích xuất tham số GeeTest

GeeTest cần ba tham số. gt cố định cho mọi request, còn challenge đổi theo từng phiên làm việc — nên bạn phải lấy challenge mới trước mỗi lần giải.

Cách 1 — tab Network:

Bước Thao tác
1 Mở DevTools → tab Network
2 Lọc theo register-slide, gettype.php hoặc get.php
3 Kích hoạt captcha trên trang và tìm request khởi tạo
4 Response trả về gt, challenge, và đôi khi cả api_server
{
  "success": 1,
  "gt": "019924a82c70bb123aae90d483087f94",
  "challenge": "12345678abc90def12345678abc90def",
  "new_captcha": true
}

Cách 2 — đọc mã nguồn trang:

// Search page source for initGeetest or gt value
document.querySelectorAll('script').forEach(s => {
  if (s.textContent.includes('initGeetest')) {
    console.log(s.textContent);
  }
});

Cách 3 — endpoint API riêng của trang:

Nhiều trang web tự lấy tham số GeeTest từ API riêng của họ:

# 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"]

Bước 2: gửi task tới CaptchaAI

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;
}

Bước 3: polling để lấy kết quả

  • CaptchaAI trả về ba giá trị khi giải xong: challenge, validateseccode
  • Cứ mỗi 5 giây, bạn gọi lại res.php để hỏi kết quả cho đến khi có phản hồi — đây là polling (chủ động hỏi định kỳ), không phải bỏ phiếu

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');
}

Bước 4: gửi kết quả về trang đích

  • Gộp geetest_challenge, geetest_validate, geetest_seccode cùng dữ liệu form đăng nhập
  • Gửi request POST chứa cả ba giá trị tới endpoint xác thực của trang web
# 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}")

Ví dụ Python đầy đủ

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}")

Khắc phục sự cố

  • ERROR_BAD_PARAMETERS — thiếu gt hoặc challenge, trích xuất lại từ trang
  • ERROR_CAPTCHA_UNSOLVABLE — challenge hết hạn hoặc không hợp lệ, lấy challenge mới
  • Trang web từ chối kết quả — challenge cũ chỉ dùng một lần, lấy mới cho mỗi lần thử
  • geetest_validate rỗng — giải thất bại phía CaptchaAI, thử lại với challenge mới

Ví dụ đầy đủ chạy được ngay

Cần một dự án chạy được ngay, có sẵn thiết lập môi trường, polling, retry và xử lý lỗi?

Xem ví dụ đầy đủ trên GitHub →


Câu hỏi thường gặp

CaptchaAI có giải được GeeTest v4 không?

Chưa. GeeTest v4 dùng giao thức xác minh khác hoàn toàn so với v3, và CaptchaAI hiện chưa hỗ trợ — tính năng này đang trong lộ trình "sắp ra mắt". Nếu trang web bạn cần test đã nâng cấp lên v4, quy trình trong bài này chưa áp dụng được.

api_server dùng để làm gì và khi nào cần khai báo?

Tham số này chỉ định máy chủ GeeTest xử lý xác minh, phổ biến nhất là api.geetest.com hoặc api-na.geetest.com. Chỉ cần khai báo khi trang web dùng máy chủ tùy chỉnh khác với mặc định; nếu không chắc, bỏ trống và CaptchaAI vẫn xử lý được ở hầu hết trường hợp.

Giải GeeTest v3 qua CaptchaAI tốn bao nhiêu?

  • CaptchaAI tính phí theo thread, không theo từng lần giải
  • Gói BASIC ($15/tháng, 5 thread) đủ cho hầu hết dự án kiểm thử tích hợp
  • Mỗi thread giải không giới hạn số lần trong tháng, chi phí không tăng theo số request gửi tới in.php

Vì sao vẫn gặp ERROR_CAPTCHA_UNSOLVABLEgtchallenge đã trích xuất đúng?

  • Nguyên nhân phổ biến nhất: challenge đã dùng ở lần thử trước hoặc đã hết hạn, giá trị này chỉ dùng một lần
  • Luôn lấy challenge mới ngay trước khi gọi in.php, không tái sử dụng giá trị đã log lại

Nên dùng polling hay webhook để lấy kết quả GeeTest?

  • Khối lượng nhỏ, script kiểm thử: polling res.php như trong bài là đủ và dễ triển khai
  • Hệ thống chạy liên tục, khối lượng lớn: callback (webhook) giảm request thừa vì CaptchaAI tự gửi kết quả về URL của bạn ngay khi giải xong

Hướng dẫn liên quan

Os comentários estão desativados para este artigo.