wulu-geetest-bypass-nine
Offline nine-grid solver for Geetest v4 CAPTCHAs. The challenge is a 3×3 grid plus a prompt icon; the solver picks the cells that show the same object and returns their grid positions.
Works either way: as a plugin of
wulu-geetest-bypass, which adds
click-track generation and submission, or standalone — the package exports
solve_nine() and imports nothing from the main package.
How it works
A single end-to-end ONNX neural classifier:
- Prompt class lookup: The prompt icon's MD5 hash is matched against the
class registry (from ONNX custom metadata
classesor environment variables), resolving the target category index. - Grid preprocessing:
- The grid image carries a 2px black bar at the bottom (all collected
samples do), so
bar_rows()trims it before cutting. - The three-way boundaries start at
ceil(i * h / 3)— the real seams sit at rows 87 and 173 of the 259-tall content (i.e.ceil(86.33)andceil(172.67)), while every cell ish // 3 = 86tall, cleanly dropping the seam row:
- The grid image carries a 2px black bar at the bottom (all collected
samples do), so
0..85 87..172 173..258 86 rows each, seams exactly between cells
- Batch inference:
- All 9 cells are cropped, resized to the model's expected resolution (auto-detected from the ONNX graph, default 128×128), and normalized with ImageNet mean and std.
- The resulting tensor of shape
(9, 3, H, W)is fed intonine.onnxin a single forward pass. - The logits corresponding to the target prompt class index
logits[:, target_idx]rank the cells by matching confidence. - The top
nine_numscells are returned in click order.
Model
| File | Size | Type | Input Shape | Output Shape |
|---|---|---|---|---|
nine.onnx |
~14 MiB | CNN Classifier | image [batch, 3, 128, 128] |
logits [batch, num_classes] |
Category metadata (classes) is embedded directly in the ONNX file's custom
metadata map as a comma-separated list of prompt icon hashes.
Custom Model Integration
You can provide your own trained ONNX model weights without modifying any code. Point the environment variable NINE_MODEL_PATH to your model file:
export NINE_MODEL_PATH=/path/to/your_custom_model.onnx
Model Requirements
-
Input Tensor:
- Shape:
[batch, 3, H, W](e.g.[batch, 3, 128, 128],[batch, 3, 224, 224], or arbitraryH×W). The solver automatically inspects the ONNX graph's input shape to resize candidate cells. If dimensions are dynamic or unspecified, it defaults to128×128. - Node name: Arbitrary (auto-detected via
session.get_inputs()[0].name). - Normalization: RGB format normalized with ImageNet statistics:
mean = [0.485, 0.456, 0.406],std = [0.229, 0.224, 0.225].
- Shape:
-
Output Tensor:
- Shape:
[batch, num_classes]returning raw classification logits for each grid cell. - Node name: Arbitrary (auto-detected via
session.get_outputs()[0].name).
- Shape:
-
Class Mapping (
classes): The solver matches each prompt icon by its MD5 hex digest against the target output column index. You can provide this mapping via either of two methods:- Method A (Recommended — Embed into ONNX metadata):
import onnx model = onnx.load('your_model.onnx') meta = model.metadata_props.add() meta.key = 'classes' meta.value = ','.join(class_md5_hashes) # e.g. "0259c3ab...,16a04e9c..." onnx.save(model, 'your_model.onnx')
- Method B (Environment Variables):
- Set
NINE_CLASSES_PATH=/path/to/classes.txt(newline-separated or comma-separated list of hashes, or a JSON array), or - Set
NINE_CLASSES=hash1,hash2,hash3,....
- Set
- Method A (Recommended — Embed into ONNX metadata):
Performance
Single process, CPU (CPUExecutionProvider), batched 9-cell inference:
| Function | Latency (CPU) |
|---|---|
solve_nine |
~15–25 ms |
Download
The model file is fetched on first use into
platformdirs.user_cache_dir('wulu-geetest-bypass', appauthor=False) / 'nine'
and SHA-256 verified against the registry in hub.py.
hub.py also runs as a script, which fetches the file up front instead of
waiting for the first challenge:
python -m wulu_geetest_bypass_nine.hub
If huggingface.co is unreachable, point HF_ENDPOINT at a mirror — the same
variable huggingface_hub reads:
export HF_ENDPOINT=https://hf-mirror.com
HF_ENDPOINT is read when the package is first imported, so set it before the
solver runs.
Usage
As a plugin of the main package:
uv add wulu-geetest-bypass[nine]
The solver registers as an entry point of the wulu_geetest_bypass.solvers
group under the nine captcha type, and is discovered automatically by
wulu_geetest_bypass.
from wulu_geetest_bypass import Geetest
solver = Geetest(captcha_id='your_captcha_id', risk_type='nine')
seccode = await solver.resolve()
Or standalone:
pip install wulu-geetest-bypass-nine
from wulu_geetest_bypass_nine import solve_nine
cells = solve_nine(grid_bytes, [prompt_bytes], 3)
# [[row, col], ...] 1-based, in click order — e.g. [[1, 1], [3, 3], [1, 3]]
Grid positions are 1-based on both axes, matching the SDK's userresponse
(dataId is 1..3); score_nine() returns the same ranking as raw logits if
you need the scores.
Metadata
Release files for wulu-geetest-bypass-nine 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| wulu_geetest_bypass_nine-0.1.0.tar.gz | 7.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wulu_geetest_bypass_nine-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.7 kB
Release files / wulu_geetest_bypass_nine-0.1.0.tar.gz
| Download URL | wulu_geetest_bypass_nine-0.1.0.tar.gz |
|---|---|
| Size | 7.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
43a1d3e57c2518f5ba974e75f31babdb21ea69611da19f147672b853ac77e60a
|
|
BLAKE2b-256 checksum How to use checksums |
8127a1ebff17b22018090e9d98666b2ca082b1412b355617c64f383ea49bef8c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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_nine-0.1.0-py3-none-any.whl
| Download URL | wulu_geetest_bypass_nine-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
10c6ebdd07c47dc56dc7b21b611bc5e1aa8e8895469cbba75efcef5741814f21
|
|
BLAKE2b-256 checksum How to use checksums |
a92b69ac8c0770e570681d3edea64141971e0d14f5fd807822e39f38fedd2349
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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}
|
Security for wulu-geetest-bypass-nine 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.