Auto-Captcha
Auto-detect and solve captchas during Playwright browser automation using the NopeCHA API.
When to Use
- Browser automation hits a captcha wall
- Web scraping tasks need captcha bypass
- Automated testing against captcha-protected sites
- Any Playwright script that might encounter hCaptcha or reCAPTCHA v2
Prerequisites
NOPECHA_API_KEYenv var set (get free credits at https://nopecha.com)- Python
requestsandplaywrightinstalled - Playwright browser installed (
python -m playwright install chromium)
Quick Start
from auto_captcha_solver import CaptchaSolver
solver = CaptchaSolver(api_key="your-key")
# Auto-detect + solve + inject (one-liner)
results = solver.auto_solve(page)
Full API
Detect
captchas = solver.detect(page)
# Returns: [{"type": "hcaptcha"|"recaptcha2", "sitekey": "...", "url": "...", "frame": ...}]
Solve
result = solver.solve("hcaptcha", sitekey, page_url)
# Returns: CaptchaResult(success=True, token="...", attempts=5, elapsed_sec=38.0)
Inject
solver.inject(page, "hcaptcha", token)
# Injects token into page's captcha callback
Auto (detect + solve + inject)
results = solver.auto_solve(page)
for r in results:
print(f"{r.captcha_type}: {'OK' if r.success else r.error}")
SmartPage (transparent wrapper)
from auto_captcha_solver import smart_page
with smart_page(api_key="your-key") as page:
page.goto("https://protected-site.com")
page.fill("#email", "user@example.com")
page.click("#submit") # captcha auto-solved after each action
Supported Captcha Types
| Type | API Endpoint | Status |
|---|---|---|
| hCaptcha (checkbox) | /v1/token/hcaptcha |
Working |
| hCaptcha (enterprise) | /v1/token/hcaptcha |
Working |
| reCAPTCHA v2 | /v1/token/recaptcha2 |
Works but queue can be slow |
| reCAPTCHA v3 | /v1/token/recaptcha3 |
Working (needs data.action) |
| Cloudflare Turnstile | /v1/token/turnstile |
Working with a proxy — proxy is Required in NopeCHA's schema for this endpoint (solver exit IP must match browser IP); check_proxy_egress() / CLI proxy-check verify first. Error 10 bodies carry a diagnostic type field, now surfaced in the error string. |
Stealth & Context Cloning (v0.1.6)
apply_stealth(context) masks the in-page headless leaks (navigator.webdriver,
window.chrome, navigator.plugins, WebGL vendor string). Call right after
browser.new_context(...).
from auto_captcha_solver import CaptchaSolver, apply_stealth
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context()
apply_stealth(context) # mask fingerprint
page = context.new_page()
solver = CaptchaSolver(api_key="your-key")
results = solver.auto_solve(page) # clones UA + cookies automatically
auto_solve(..., clone_context=True) (default) forwards the browser's real
User-Agent and cookies to NopeCHA so the token is minted in a context matching
the presenting browser. Turnstile solves without a proxy emit a warning, because
Cloudflare requires the solver IP to match the client IP.
Turnkey Autopilot
from auto_captcha_solver import auto_solve_url
report = auto_solve_url("https://site.com", api_key="key", stealth=True)
print(report.summary) # "https://site.com — hcaptcha:OK"
# proxy_pool=[...] + round_robin_rotator rotate proxies per session;
# auto_solve_page(page, solver) solves captchas on a page you already own.
NopeCHA API Details
- Base URL:
https://api.nopecha.com - Auth:
Authorization: Basic <API_KEY>header (NOT query param, NOT Bearer) - Status check:
GET /v1/status - Submit hCaptcha:
POST /v1/token/hcaptchabody{"sitekey": "...", "url": "..."} - Submit reCAPTCHA:
POST /v1/token/recaptcha2body{"sitekey": "...", "url": "..."} - Poll result:
GET /v1/token/<type>?id=<job_id> - Response:
{"data": "<token>"}on success,{"error": 14}= still in queue (retryable), other errors = fail - hCaptcha solves fast (~30-40s). reCAPTCHA queue is often slow (60-120s+).
Pitfalls
- reCAPTCHA queues can be slow — may take 60-120+ seconds during peak times
- hCaptcha iframe detection — look for
hcaptcha.comin frame URLs; some sites load hCaptcha without an iframe (use DOM fallback:document.querySelector('[data-sitekey]')). Always addtime.sleep(3)after page load for lazy loading. - reCAPTCHA iframe detection — look for
recaptchaAND/anchorin frame URL; the?k=<sitekey>param has the key - reCAPTCHA callback injection — needs
___grecaptcha_cfgto exist; if site uses enterprise, injection may fail silently - Credits — each solve costs 1 credit; check with
solver.get_credits() - Headless detection — some sites detect headless browsers; use
headless=Falseor stealth plugins if needed
Installation
pip install auto-captcha-solver
python -m playwright install chromium
MCP Server
Works with Claude Code, OpenClaw, and any MCP-compatible agent:
claude mcp add auto-captcha-solver -- python -m auto_captcha_solver.mcp_server
File Location
~/.hermes/skills/auto-captcha-solver/