Developer GuideGeeTest v3 & v4

How to Solve GeeTest v3 & v4 Captcha in Python

GeeTest is one of the most widely deployed interactive security challenges, protecting cryptocurrency exchanges, gaming portals, and ticketing platforms. This guide demonstrates how to solve both GeeTest v3 and v4 slider, icon, and gobang challenges using Python, Playwright, and the 2Captcha API.

1. GeeTest v3 vs GeeTest v4: Key Differences

Before writing automation scripts, it is essential to determine whether the target application uses GeeTest v3 or v4:

  • GeeTest v3: Requires two parameters: gt (static public key) and challenge (dynamic session token generated by the target server on each page request). Upon solving, it returns geetest_challenge, geetest_validate, and geetest_seccode.
  • GeeTest v4 (Adaptive): Streamlined architecture requiring only a static captcha_id and the page URL. The solution returns lot_number, pass_token, gen_time, and captcha_output.

2. Installing Required Packages

Install the official 2captcha-python library alongside playwright:

pip install 2captcha-python playwright
playwright install chromium

3. Solving GeeTest v4 with Python

GeeTest v4 is solved by passing the captcha_id and the page URL directly to 2Captcha:

import os
from twocaptcha import TwoCaptcha

api_key = os.getenv("TWOCAPTCHA_API_KEY")
solver = TwoCaptcha(api_key)

try:
    print("Dispatching GeeTest v4 task to 2Captcha...")
    # GeeTest v4 requires captcha_id and target page URL
    result = solver.geetest_v4(
        captcha_id="e392e1d704d3b36331a39c1e02c3b735",
        url="https://example.com/login"
    )
    print("GeeTest v4 solved successfully!")
    print(f"Captcha Output: {result}")
    # Result returns: captcha_id, lot_number, pass_token, gen_time, captcha_output
except Exception as e:
    print(f"GeeTest v4 solve error: {e}")

4. Solving GeeTest v3 with Python

For GeeTest v3 endpoints, pass the gt key and dynamic challenge token:

import os
from twocaptcha import TwoCaptcha

api_key = os.getenv("TWOCAPTCHA_API_KEY")
solver = TwoCaptcha(api_key)

try:
    print("Dispatching GeeTest v3 task to 2Captcha...")
    # GeeTest v3 requires gt, challenge, and target URL
    result = solver.geetest(
        gt="f2b05c3343a23338b55de4d0b04453b7",
        challenge="1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
        url="https://example.com/v3-login"
    )
    print("GeeTest v3 solved!")
    # Result contains: challenge, validate, seccode
    print(f"Validate: {result['code']['geetest_validate']}")
except Exception as e:
    print(f"GeeTest v3 solve error: {e}")

5. Full Playwright Automation & Callback Injection

In production scraping scripts, you integrate the solver with Playwright to extract the challenge parameters, dispatch the task asynchronously, and invoke the form callback without user interaction:

import asyncio
import os
from playwright.async_api import async_playwright
from twocaptcha import TwoCaptcha

API_KEY = os.getenv("TWOCAPTCHA_API_KEY")
solver = TwoCaptcha(API_KEY)
TARGET_URL = "https://example-geetest-v4-target.com/login"

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
        )
        page = await context.new_page()

        print(f"Navigating to {TARGET_URL}...")
        await page.goto(TARGET_URL)

        # 1. Intercept or extract the GeeTest v4 captcha_id from the page
        captcha_id = await page.evaluate("""() => {
            # GeeTest v4 script init config usually holds the captcha_id
            return window.initGeetest4?.captcha_id || document.querySelector('[data-captcha-id]')?.getAttribute('data-captcha-id') || 'e392e1d704d3b36331a39c1e02c3b735';
        }""")

        print(f"Found GeeTest v4 captcha_id: {captcha_id}")
        print("Dispatching task to 2Captcha solver network...")

        # 2. Request solution from 2Captcha
        result = solver.geetest_v4(
            captcha_id=captcha_id,
            url=TARGET_URL
        )
        data = result["code"]
        print("Received GeeTest token solution!")

        # 3. Inject callback parameters directly into page form or invoke handler
        await page.evaluate("""(tokenData) => {
            # Call GeeTest v4 onsuccess callback with solved tokens
            if (window.geetestV4Handler?.onSuccess) {
                window.geetestV4Handler.onSuccess(tokenData);
            } else {
                # Fallback: fill hidden form inputs
                for (const [key, val] of Object.entries(tokenData)) {
                    let input = document.querySelector('input[name="' + key + '"]');
                    if (input) input.value = val;
                }
            }
        }""", data)

        # 4. Submit form
        print("Submitting login form with validated GeeTest token...")
        await page.click("#btn-submit")
        await page.wait_for_load_state("networkidle")

        print("Navigation completed! Final URL:", page.url)
        await browser.close()

if __name__ == "__main__":
    asyncio.run(main())

6. Why 2Captcha is the #1 Solver for GeeTest

2Captcha GeeTest Benchmark

Rank #1 GeeTest Solver
  • All Challenge Types Supported: Slide, Icon recognition, Gobang, Nine-box puzzle
  • Average Solution Time: 5.4 seconds
  • Pass Rate: 99.8% verification rate on live endpoints
  • Transparent Pricing: From $1.50 per 1,000 requests, pay-as-you-go
Get 2Captcha API Key ($1.50/1k) →