Skip to main content

wulu-geetest-bypass

GitHub Actions Workflow Status Python License Geetest v4 downloads

English | 简体中文

A lightweight, pure Python library to automatically solve Geetest Behavioral CAPTCHA v4 without Node.js or headless browsers. Features dynamic mouse trajectory simulation, 7 built-in risk type solvers, accessible voice bypass, and an extensible custom solver registry.

✨ Features

  • 🚀 Pure Python 3.11+ — Zero Node.js, headless browsers, or external runtime dependencies required.
  • 🛡️ Multi-Risk Type Support — Out-of-the-box solvers for 7 risk types (see full table).
  • 🎯 Human-like Track Simulation — Dynamically generated mouse trajectories for every run (no fixed replays).
  • 🔁 Smart Auto-Retry — One-call resolve() automatically retries up to 3 times on transient failures.
  • 🕹️ Granular Step-by-Step Flow — Separate load() and verify() steps for intercepting payloads and tokens.
  • ♿ Accessible Voice Bypass — Seamlessly switch to offline speech recognition when the voice channel is enabled.
  • 🔌 Extensible Solver Registry — Easily plug in custom OCR / Vision models, or override built-in solvers.
  • 🌐 Advanced Networking — Native support for proxy chains, browser TLS fingerprint emulation, and custom headers.

🧩 Supported Risk Types

Type Description Dependency Support
ai Silent verification none ✅
slide Slider puzzle [slide] ✅
match 3×3 connect none ✅
winlinze Gomoku none ✅
svg_seed SVG 3x3 image selection [svg] ✅
svg_icon SVG 2x2 icon selection [svg] ✅
voice Voice verification [voice] ✅
icon Icon click none ❌
word Word click none ❌
nine Nine-grid none ❌
phrase Phrase recognition none ❌
pencil Doodle none ❌
space Spatial reasoning none ❌

The Dependency column refers to the dependency groups below. Types marked ❌ have no built-in solver — register your own via custom solvers.

📦 Installation

uv is recommended (faster, more modern Python package manager):

uv add "wulu-geetest-bypass[all]"

You can also use pip:

pip install "wulu-geetest-bypass[all]"

Dependency groups (install only what you need):

# voice verification
uv add "wulu-geetest-bypass[voice]"

# slide puzzle (requires opencv)
uv add "wulu-geetest-bypass[slide]"

# SVG icon & seed selection
uv add "wulu-geetest-bypass[svg]"

# Install everything
uv add "wulu-geetest-bypass[all]"

🚀 Quick Start

import asyncio
from wulu_geetest_bypass import Geetest


async def main():
    g = Geetest(captcha_id='your_captcha_id', risk_type='slide')
    result = await g.resolve()
    print(result)
    # {
    #     "captcha_id": "xxx",
    #     "lot_number": "xxx",
    #     "pass_token": "xxx",
    #     "gen_time": "xxx",
    #     "captcha_output": "xxx"
    # }


asyncio.run(main())

That is all you need for the common case. See Advanced Usage for retry control, the step-by-step flow, voice mode, custom solvers, and HTTP configuration.

💡 Advanced Usage

Automatic retry and one-call resolve()

resolve() is load() + verify() in one call, with automatic retry on failure:

g = Geetest(captcha_id='your_captcha_id', risk_type='slide')
result = await g.resolve()  # default: up to 3 attempts
result = await g.resolve(retry=5)  # override the attempt count

On the final failure it raises VerifyError instead of returning a partial result.

Step-by-step flow: load() → verify()

When you need to intervene between the two stages (log, inspect the payload, run your own recognition), call them separately:

g = Geetest(captcha_id='your_captcha_id', risk_type='slide')
data = (
    await g.load()
)  # init data: captcha_type, lot_number, payload, process_token, pow_detail, ...
response = await g.verify(data)  # full response: status + data

load() returns a dict whose fields can be passed directly into verify(). The return types are listed under Data Models.

Accessible (voice) mode

Some Geetest v4 sites enable the voice channel (accessible mode) server-side. When a site supports it, regardless of the original risk type, you can force voice verification via voice=True, bypassing the original slider / click behavioral checks:

# Originally a slide verification, but the site supports accessible mode
g = Geetest(captcha_id='your_captcha_id', risk_type='slide', voice=True)
result = await g.resolve()

The flow becomes: load voice captcha → download audio → recognize digits offline → submit verification. No browser environment or image recognition needed.

Note: Not all sites enable the accessible channel. If unsupported, the show_voice field in load() returns false, and setting voice=True has no effect — the original risk_type is still used.

Register custom solvers

For risk types without built-in support, inject a custom solver via register_solver:

from wulu_geetest_bypass import Geetest


def solve_icon(imgs: bytes, ques: list[bytes]) -> list[tuple[float, float]]: ...


Geetest.register_solver('icon', solve_icon)

Once registered, generate_w() calls it automatically with the corresponding payload fields. Click/draw solvers return normalized coordinates in [0, 1] relative to the verification image — the library takes care of scaling them to the window/payload formats (e.g. userresponse uses image-based percent × 10000) and of generating the click tracks (including the final submit-button click for icon/word/phrase):

Type Solver signature
icon / word (imgs: bytes, ques: list[bytes]) -> list[tuple[float, float]]
phrase (imgs: bytes) -> list[tuple[float, float]]
nine (imgs: bytes, ques: list[bytes], nine_nums: int) -> list[tuple[int, int]]
pencil (imgs: bytes) -> list
space Not built-in separately; Geetest routes space to svg_icon (solved by the SVG solver)

Built-in solvers can also be overridden, either by passing the solver directly or as a decorator:

Geetest.register_solver('slide', my_custom_slide_solver)
@Geetest.register_solver('slide')
def my_custom_slide_solver(bg, slice, ypos): ...

Proxy and HTTP client configuration

Geetest forwards all HTTP concerns to wreq, so proxies, custom headers, and client emulation are configured once at construction time. Pass a ClientConfig via client_options, or an already-constructed client via client (which takes priority):

from wreq import Client, ClientConfig

config = ClientConfig(...)  # proxy chains, headers, emulation, timeouts, ...

g = Geetest(captcha_id='your_captcha_id', risk_type='slide', client_options=config)
# equivalent, when you need to build the client yourself first:
g = Geetest(captcha_id='your_captcha_id', risk_type='slide', client=Client(config))

📖 API Reference

Configuration — Geetest(**options)

Parameter Type Description
captcha_id str Verification ID (required)
risk_type RiskType Risk type, default 'ai'
client_type ClientType Client type, 'web' / 'web_mobile' / 'android' / 'ios'
lang Lang Language, 'zho' / 'eng' / 'fra' / 'deu' and 13 more
challenge str Custom challenge (auto-generated if omitted)
user_info Any Extra user info (reserved)
voice bool Enable accessible voice verification (requires [voice])
client_options wreq.ClientConfig HTTP client config (proxy, headers, emulation, etc.)
client wreq.Client | None Custom HTTP client (takes priority over client_options)

Data models

load() -> dict returns init data containing captcha_type, lot_number, payload, process_token, pow_detail and other fields, passable directly into verify().

verify(data) -> VerifyResponse:

class VerifyResponse:
    status: str  # "success" / "fail" / "error"
    data: VerifyData  # verification result data


class VerifyData:
    lot_number: str
    result: str  # "success" / "fail"
    fail_count: int
    seccode: Seccode
    score: str
    payload: str
    process_token: str
    payload_protocol: int

resolve(retry=3) -> Seccode:

class Seccode:
    captcha_id: str
    lot_number: str
    pass_token: str
    gen_time: str
    captcha_output: str
Parameter Type Description
retry int Retry count on failure, default 3

Exceptions

Exception Description
GeetestError Base class of all custom exceptions
VerifyError Verification failed (all retries exhausted)

⚖️ Disclaimer

This project is for learning and research purposes only. Users should comply with applicable laws and platform terms of service; any illegal use is prohibited. The author assumes no responsibility for any legal issues arising from the use of this project.

🤝 Support & Updates

  • This project continuously tracks Geetest v4 behavioral verification changes and updates the bypass logic and solvers promptly.
  • Please open an Issue if you encounter problems, and PRs are welcome.
  • If this project helps you, feel free to give it a ⭐ Star to encourage continued development.

📄 License

Released under the MIT License — see LICENSE.

Metadata

Release files for wulu-geetest-bypass 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wulu-geetest-bypass 0.3.2
File Size Uploaded
wulu_geetest_bypass-0.3.2.tar.gz 136.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wulu-geetest-bypass 0.3.2
File Interpreter ABI Platform
wulu_geetest_bypass-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 166.6 kB

Release files / wulu_geetest_bypass-0.3.2.tar.gz

Download URL wulu_geetest_bypass-0.3.2.tar.gz
Size 136.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5d32c989acbe350bd2b4cf5be30fb8236929b62d567bd4b0d11a1fb8f01ba5e7
BLAKE2b-256 checksum
How to use checksums
9a088d9c842892be4e903808eda9d4a69ddcaa65087f84f467f8cd4169c59539
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / wulu_geetest_bypass-0.3.2-py3-none-any.whl

Download URL wulu_geetest_bypass-0.3.2-py3-none-any.whl
Size 30.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c87a57111399b2de3465f7ba54ddf1e2588637e04fc69497914919a9a051176a
BLAKE2b-256 checksum
How to use checksums
03785768849e631644c5b3d9cd8e7f374431535d0789a1af1fce4ca3c0017375
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

This release

0.3.2 This release

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page