wulu-geetest-bypass
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()andverify()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_voicefield inload()returnsfalse, and settingvoice=Truehas no effect — the originalrisk_typeis 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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wulu_geetest_bypass-0.3.0.tar.gz.
File metadata
- Download URL: wulu_geetest_bypass-0.3.0.tar.gz
- Upload date:
- Size: 136.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65d14a24961df25c92053fe8acd5f6ee10641b0104082a3d2dc5f96be69d30ff
|
|
| MD5 |
764b7d27e61a9457db479129e8b9e33d
|
|
| BLAKE2b-256 |
ef53b069b74c667c06829fde2544b4fb91a664b59961d5229443ddff1ceac176
|
File details
Details for the file wulu_geetest_bypass-0.3.0-py3-none-any.whl.
File metadata
- Download URL: wulu_geetest_bypass-0.3.0-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d38e73245dffe650e8ce59e55421e9f4f075f72ddf6adb0b1934f2fb76656e3f
|
|
| MD5 |
bbbd9aa8f3bbf3ede4a0fdadd9b26bfd
|
|
| BLAKE2b-256 |
429b985d56c3d2b125fdae965be48ae26178cee21b49a9d3c8f5458e3dbeaeb2
|