AI powered reCAPTCHA solver for reCAPTCHA v2 and v3 using YOLO based vision models (57k images dataset). The library provides both synchronous and asynchronous APIs, to automate image challenge solving and token extraction.
https://github.com/user-attachments/assets/3d0de5bd-6bbd-4a1a-bb06-fd7efa9d55fd
recaptcha-domain-replicator spins up a local HTTPS server and replicates the target reCAPTCHA widget.This project uses RecaptchaDomainReplicator (from recaptcha-domain-replicator) to build the local replica page and launch the browser session. It creates a new replicator, starts a local HTTPS server, and returns the browser instance plus a token handle.
pip install vision-ai-recaptcha-solver
From source (recommended for development):
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[dev]"
from vision_ai_recaptcha_solver import RecaptchaSolver, SolverConfig
config = SolverConfig(
timeout=200,
# Optional: point to a specific Chromium binary
# browser_path="path/to/chrome.exe",
# proxy="http://username:password@ip:port",
)
with RecaptchaSolver(config) as solver:
result = solver.solve(
website_key="your_site_key",
website_url="https://example.com/your-page-with-recaptcha",
)
print(result.token)
print(result.captcha_type.value)
print(result.time_taken)
print(result.attempts)
from vision_ai_recaptcha_solver import RecaptchaSolver, SolverConfig
config = SolverConfig(timeout=120)
with RecaptchaSolver(config) as solver:
result = solver.solve(
website_key="your_site_key",
website_url="https://example.com/login",
is_invisible=True,
action="login",
is_enterprise=False,
api_domain="google.com",
cookies=None,
user_agent=None,
)
print(result.token)
import asyncio
from pathlib import Path
from vision_ai_recaptcha_solver import AsyncRecaptchaSolver, SolverConfig
async def main():
config = SolverConfig(
timeout=180,
server_port=8443,
download_dir=Path("tmp1"),
)
async with AsyncRecaptchaSolver(config) as solver:
result = await solver.solve(
website_key="your_site_key",
website_url="https://example.com/your-page-with-recaptcha",
)
print(result.token)
asyncio.run(main())
Each solver instance should use a distinct server_port and download_dir to avoid conflicts.
import asyncio
from pathlib import Path
from vision_ai_recaptcha_solver import AsyncRecaptchaSolver, SolverConfig
async def solve_one(name: str, config: SolverConfig):
async with AsyncRecaptchaSolver(config) as solver:
result = await solver.solve(
website_key="your_site_key",
website_url="https://example.com/your-page-with-recaptcha",
)
return name, result
async def main():
config_a = SolverConfig(server_port=8443, download_dir=Path("tmp-a"))
config_b = SolverConfig(server_port=8444, download_dir=Path("tmp-b"))
results = await asyncio.gather(
solve_one("A", config_a),
solve_one("B", config_b),
)
for name, result in results:
print(name, result.captcha_type.value, result.time_taken)
asyncio.run(main())
The package exposes a console script:
vision-ai-recaptcha-solver --help
Solve a captcha:
vision-ai-recaptcha-solver solve \
--website-key "your_site_key" \
--website-url "https://example.com/your-page-with-recaptcha" \
--no-headless \
--timeout 180 \
--output json
Solve invisible reCAPTCHA (v3):
vision-ai-recaptcha-solver solve \
--website-key "your_site_key" \
--website-url "https://example.com/login" \
--invisible \
--action "login"
Run a demo against Google's test page:
vision-ai-recaptcha-solver demo
SolverConfig controls runtime behavior and validation.
| Option | Default | Description |
|---|---|---|
model_path |
None |
Path to the classification ONNX model. If None, auto downloads from Hugging Face. |
detection_model_path |
None |
Path to detection model. If None, uses yolo12x.pt. |
download_dir |
Path("tmp") |
Directory for downloaded images and temp files. |
server_port |
8443 |
Local HTTPS port used by the replicator. |
proxy |
None |
Proxy URL in protocol://[user:pass@]host:port format. |
browser_path |
None |
Path to Chromium executable. Auto detected if omitted. |
headless |
False |
Run browser in headless mode. |
timeout |
300.0 |
Max seconds to wait for token extraction. |
max_attempts |
12 |
Max attempts for solving a challenge. |
human_delay_mean |
0.2 |
Mean delay in seconds between interactions. |
human_delay_sigma |
0.1 |
Standard deviation for human like delays. |
log_level |
"WARNING" |
Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL). |
persist_html |
False |
Persist the generated HTML replicas. |
verbose |
False |
Enable verbose output. |
conf_threshold |
0.7 |
Tile classification confidence threshold. |
min_confidence_threshold |
0.2 |
Minimum confidence for top 3 tiles (3x3). |
fourth_cell_threshold |
0.7 |
Confidence threshold to include 4th cell. |
detection_conf_threshold |
0.6 |
Confidence threshold for 4x4 detection. |
default_timeout |
10.0 |
Default timeout for browser operations. |
image_download_retries |
3 |
Image download retries. |
image_download_retry_delay |
1.0 |
Base delay between retries. |
register_signal_handlers |
True |
Register SIGINT/SIGTERM handlers for cleanup. |
cleanup_tmp_on_close |
True |
Delete download_dir when solver closes. |
Both RecaptchaSolver.solve() and AsyncRecaptchaSolver.solve() support:
website_key: reCAPTCHA site key (required)website_url: URL containing the challenge (required)is_invisible: Whether this is invisible/v3 (default False)action: Action name for invisible reCAPTCHA (optional)is_enterprise: Whether this is enterprise reCAPTCHA (default False)api_domain: google.com or recaptcha.net (default google.com)bypass_domain_check: Skip domain verification (default True)use_ssl: Use HTTPS for local server (default True)cookies: Optional list of cookie dictionaries to set before solvinguser_agent: Optional custom user agent stringSolveResult is returned for successful solves:
token: reCAPTCHA response tokencookies: cookies from the browser sessiontime_taken: wall clock time in secondscaptcha_type: one of dynamic_3x3, selection_3x3, square_4x4, invisible, no_challenge, unknownattempts: number of solve attemptsrecaptcha_classification_57k.onnxSolverConfig(model_path=...).yolo12x.ptultralytics (auto downloaded if not present).SolverConfig(detection_model_path=...).The repo includes two runnable demos that hit Google's public test page and show token extraction timing and captcha type detection. Treat them as templates.
demo.py: synchronous solve with RecaptchaSolverpython demo.pydemo_async.py: async workflows with AsyncRecaptchaSolverpython demo_async.pyRun tests:
pytest
src/vision_ai_recaptcha_solver/ - core librarysrc/vision_ai_recaptcha_solver/captcha/ - handlers for challenge typessrc/vision_ai_recaptcha_solver/detector/ - YOLO model integrationsrc/vision_ai_recaptcha_solver/models/ - model assetstests/ - unit testsdemo.py, demo_async.py - example scriptsbrowser_path does not exist: Pass a valid Chromium executable path in SolverConfig(browser_path=...).
On Windows, the path should end with .exe.Invalid proxy URL format: Proxy must be protocol://[user:pass@]host:port. Supported protocols:
http, https, socks4, socks5. [] means optional.CaptchaNotFoundError or ElementNotFoundError: Confirm website_url points to a page that
renders the reCAPTCHA iframe and that the website_key matches that page.Port or temp directory conflicts: When running multiple solvers, set unique server_port and
download_dir values, or let them auto-select by not setting those fields explicitly.RecaptchaDomainReplicator is provided for educational and research purposes. Use responsibly and comply with all applicable laws and terms of service.
This project is licensed under the MIT License.
$ claude mcp add VisionAIRecaptchaSolver \
-- python -m otcore.mcp_server <graph>