API Tutorials

Solve GeeTest v3 CAPTCHA with Python and CaptchaAI

GeeTest v3 is an interactive CAPTCHA that requires users to drag a puzzle piece into place or select images in a specific sequence. Unlike token-based CAPTCHAs, GeeTest v3 returns three values — challenge, validate, and seccode — that must be submitted together to the target site.

This guide walks you through extracting the GeeTest parameters, submitting them to CaptchaAI, polling for the solution, and injecting the result.


Prerequisites

Item Value
CaptchaAI API key From captchaai.com
Python 3.7+
Library requests (pip install requests)
Target page A page with GeeTest v3 CAPTCHA

How GeeTest v3 parameters work

GeeTest v3 loads a challenge token dynamically. Each challenge is single-use and expires quickly, so you must extract a fresh one immediately before solving.

Parameter Source Notes
gt Static in page source or API response Public site key, usually constant
challenge Dynamic — loaded with each CAPTCHA render Must be fresh; expires after use or timeout
api_server Optional — in initGeetest config e.g., api-na.geetest.com
pageurl Full URL where the CAPTCHA appears Must match the page the challenge loaded on

Step 1: Extract GeeTest parameters

Find gt and challenge from the target page. They are usually in the initGeetest JavaScript call or returned from an API endpoint.

import requests

# Many sites expose GeeTest params via an API endpoint
geetest_api = "https://example.com/api/geetest/register"
resp = requests.get(geetest_api)
data = resp.json()

gt = data["gt"]               # e.g., "f1ab2cdefa3456116012345b6c78d99e"
challenge = data["challenge"]  # e.g., "12345678abc90123d45678ef90123a456b"
api_server = data.get("api_server", "api.geetest.com")

Step 2: Submit to CaptchaAI

import requests
import time
import json

API_KEY = "YOUR_API_KEY"

# Submit the GeeTest task
response = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "geetest",
    "gt": gt,
    "challenge": challenge,
    "api_server": api_server,
    "pageurl": "https://example.com/login",
    "json": 1,
})
result = response.json()

if result["status"] != 1:
    raise Exception(f"Submit failed: {result['request']}")

task_id = result["request"]
print(f"Task submitted: {task_id}")

Step 3: Poll for the solution

time.sleep(15)

for _ in range(30):
    result = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY,
        "action": "get",
        "id": task_id,
        "json": 1,
    }).json()

    if result["status"] == 1:
        solution = json.loads(result["request"])
        print(f"Challenge: {solution['challenge']}")
        print(f"Validate:  {solution['validate']}")
        print(f"Seccode:   {solution['seccode']}")
        break

    if result["request"] != "CAPCHA_NOT_READY":
        raise Exception(f"Error: {result['request']}")

    time.sleep(5)

Step 4: Inject the solution

Submit the three values to the target site's verification endpoint:

# Submit the solved GeeTest values to the target site
login_data = {
    "username": "user@example.com",
    "password": "your_password",
    "geetest_challenge": solution["challenge"],
    "geetest_validate": solution["validate"],
    "geetest_seccode": solution["seccode"],
}

resp = requests.post("https://example.com/api/login", data=login_data)
print(f"Login response: {resp.status_code}")

Complete working example

import requests
import time
import json

API_KEY = "YOUR_API_KEY"

# 1. Get fresh GeeTest parameters
geetest_resp = requests.get("https://example.com/api/geetest/register").json()
gt = geetest_resp["gt"]
challenge = geetest_resp["challenge"]

# 2. Submit to CaptchaAI
submit = requests.get("https://ocr.captchaai.com/in.php", params={
    "key": API_KEY,
    "method": "geetest",
    "gt": gt,
    "challenge": challenge,
    "pageurl": "https://example.com/login",
    "json": 1,
}).json()
task_id = submit["request"]

# 3. Poll for result
time.sleep(15)
for _ in range(30):
    poll = requests.get("https://ocr.captchaai.com/res.php", params={
        "key": API_KEY, "action": "get", "id": task_id, "json": 1
    }).json()
    if poll["status"] == 1:
        solution = json.loads(poll["request"])
        break
    if poll["request"] != "CAPCHA_NOT_READY":
        raise Exception(poll["request"])
    time.sleep(5)

# 4. Use the solution
print(f"Challenge: {solution['challenge']}")
print(f"Validate:  {solution['validate']}")
print(f"Seccode:   {solution['seccode']}")

Expected output:

Challenge: 1a2b3456cd67890e12345fab678901c2de
Validate:  09fe8d7c6ba54f32e1dcb0a9fedc8765
Seccode:   12fe3d4c56789ba01f2e345d6789c012|jordan

Common errors

Error Cause Fix
ERROR_BAD_PARAMETERS Missing gt or challenge Verify both parameters are present and non-empty
ERROR_CAPTCHA_UNSOLVABLE Challenge expired before solving Extract a fresh challenge and retry
CAPCHA_NOT_READY Still processing Continue polling every 5 seconds
ERROR_ZERO_BALANCE No funds Top up your CaptchaAI account

FAQ

How long does GeeTest v3 solving take?

Typically 15–30 seconds. The challenge parameter must stay fresh during this window.

Can I reuse a solved GeeTest response?

No. Each challenge token is single-use. You need a fresh challenge for every solve attempt.

What happens if the challenge expires?

You'll get ERROR_CAPTCHA_UNSOLVABLE. Request a new challenge from the target site and resubmit.

Does CaptchaAI support GeeTest v4?

Check the CaptchaAI documentation for the latest supported types.



Start solving GeeTest v3 with CaptchaAI →

Full Working Code

Complete runnable examples for this article in Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin & Bash.

View on GitHub →

Discussions (0)

No comments yet.