Developer Guides

Quick Start — CAPTCHA Solving in Python

This guide gets you solving CAPTCHAs in Python in under 30 minutes. It covers installation, basic reCAPTCHA v2 solving, and integration with Playwright for browser-based automation.

Installation

pip install requests playwright
playwright install chromium

For async patterns:

pip install aiohttp

Solving reCAPTCHA v2 in 15 Lines

Using CaptchaAI (compatible with 2Captcha format):

import requests, time

def solve_recaptcha_v2(api_key, page_url, site_key):
    # Submit
    r = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key, "method": "userrecaptcha",
        "googlekey": site_key, "pageurl": page_url, "json": 1,
    })
    task_id = r.json()["request"]

    # Poll
    time.sleep(5)
    for _ in range(24):
        r = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1,
        })
        if r.json()["status"] == 1:
            return r.json()["request"]
        time.sleep(5)
    raise TimeoutError("Timed out")

token = solve_recaptcha_v2("YOUR_KEY", "https://example.com", "SITE_KEY")
print("Token:", token[:30], "...")

Finding the Site Key

import re, requests

def get_sitekey(url):
    html = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}).text
    m = re.search(r'data-sitekey=["\']([^"\']+)["\']', html)
    return m.group(1) if m else None

sitekey = get_sitekey("https://target-site.com/form")
print("Site key:", sitekey)

Injecting Token with Playwright

from playwright.sync_api import sync_playwright

def submit_form_with_captcha(url, sitekey, api_key):
    token = solve_recaptcha_v2(api_key, url, sitekey)

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(url)

        # Inject token
        page.evaluate(f"""
            document.getElementById('g-recaptcha-response').value = '{token}';
            document.querySelector('[name="g-recaptcha-response"]').value = '{token}';
        """)

        # Submit form
        page.click('button[type="submit"]')
        page.wait_for_load_state("networkidle")

        result = page.content()
        browser.close()
        return result

Cloudflare Turnstile

def solve_cloudflare_turnstile(api_key, page_url, site_key):
    r = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key, "method": "turnstile",
        "sitekey": site_key, "pageurl": page_url, "json": 1,
    })
    task_id = r.json()["request"]

    time.sleep(5)
    for _ in range(20):
        r = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1,
        })
        if r.json()["status"] == 1:
            return r.json()["request"]
        time.sleep(5)
    raise TimeoutError("Timed out")

# Inject Turnstile token
def inject_turnstile_token(page, token):
    page.evaluate(f"""
        document.querySelector('[name="cf-turnstile-response"]').value = '{token}';
    """)

hCaptcha

def solve_hcaptcha(api_key, page_url, site_key):
    r = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key, "method": "hcaptcha",
        "sitekey": site_key, "pageurl": page_url, "json": 1,
    })
    task_id = r.json()["request"]

    time.sleep(5)
    for _ in range(24):
        r = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1,
        })
        if r.json()["status"] == 1:
            return r.json()["request"]
        time.sleep(5)
    raise TimeoutError("Timed out")

# Inject hCaptcha token
def inject_hcaptcha_token(page, token):
    page.evaluate(f"""
        document.querySelector('[name="h-captcha-response"]').value = '{token}';
    """)

reCAPTCHA v3

def solve_recaptcha_v3(api_key, page_url, site_key, action="verify", min_score=0.7):
    r = requests.post("https://ocr.captchaai.com/in.php", data={
        "key": api_key, "method": "userrecaptcha",
        "version": "v3", "googlekey": site_key,
        "pageurl": page_url, "action": action,
        "min_score": min_score, "json": 1,
    })
    task_id = r.json()["request"]

    time.sleep(7)
    for _ in range(20):
        r = requests.get("https://ocr.captchaai.com/res.php", params={
            "key": api_key, "action": "get", "id": task_id, "json": 1,
        })
        if r.json()["status"] == 1:
            return r.json()["request"]
        time.sleep(5)
    raise TimeoutError("Timed out")

Anti-Captcha JSON Format Alternative

If your provider uses the Anti-Captcha JSON format (Anti-Captcha, CapMonster Cloud):

def solve_recaptcha_v2_anticaptcha(api_key, page_url, site_key,
                                    base_url="https://api.anti-captcha.com"):
    import requests, time

    r = requests.post(f"{base_url}/createTask", json={
        "clientKey": api_key,
        "task": {
            "type": "RecaptchaV2TaskProxyless",
            "websiteURL": page_url,
            "websiteKey": site_key,
        },
    })
    task_id = r.json()["taskId"]

    time.sleep(5)
    for _ in range(24):
        r = requests.post(f"{base_url}/getTaskResult", json={
            "clientKey": api_key, "taskId": task_id,
        })
        data = r.json()
        if data["status"] == "ready":
            return data["solution"]["gRecaptchaResponse"]
        time.sleep(5)
    raise TimeoutError("Timed out")

# To use with CapMonster Cloud, just change base_url:
# solve_recaptcha_v2_anticaptcha(key, url, sitekey, base_url="https://api.capmonster.cloud")

Full Example: Scrape a reCAPTCHA-Protected Page

import re, requests, time
from playwright.sync_api import sync_playwright

API_KEY = "YOUR_API_KEY"  # Load from environment in production

def scrape_protected_page(url):
    # 1. Get page and extract sitekey
    html = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}).text
    m = re.search(r'data-sitekey=["\']([^"\']+)["\']', html)
    if not m:
        raise ValueError("No reCAPTCHA found on page")
    sitekey = m.group(1)

    # 2. Solve CAPTCHA
    token = solve_recaptcha_v2(API_KEY, url, sitekey)

    # 3. Use token with Playwright
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        page.goto(url)
        page.evaluate(f'document.getElementById("g-recaptcha-response").value = "{token}"')
        page.click('button[type="submit"]')
        page.wait_for_load_state("networkidle")
        content = page.content()
        browser.close()

    return content

result = scrape_protected_page("https://example.com/protected-form")
print("Success, got", len(result), "bytes")

Environment Variables Best Practice

Never hardcode API keys:

import os

API_KEY = os.environ.get("CAPTCHA_API_KEY")
if not API_KEY:
    raise EnvironmentError("CAPTCHA_API_KEY environment variable not set")

Set in your shell:

# Windows
set CAPTCHA_API_KEY=your_key_here

# macOS/Linux
export CAPTCHA_API_KEY=your_key_here

FAQ

Which provider should I use for this quick start? Any provider with a 2Captcha-compatible API works with the examples above. Change the endpoint URL and API key. CaptchaAI's endpoint (https://ocr.captchaai.com) is used in examples because it has the highest success rate in current benchmarks.

Why do my tokens expire before I can use them? The token must be injected and the form submitted within ~2 minutes of the solve completing. Reduce processing between solve and injection.

Can I use these patterns with Selenium? Yes. Replace page.evaluate(...) with driver.execute_script(...) and the rest of the pattern is the same.

What if the site uses a custom CAPTCHA widget? Inspect the form's hidden input fields. Most custom widgets still submit a standard token. Identify the field name and inject accordingly.


See provider rankings at captcharank.com/solvers.

Production Readiness Notes

Use Quick Start — CAPTCHA Solving in Python as a decision and implementation aid, not just as a one-time reference. The practical test for captcha solving python quick start is whether the same approach behaves reliably when traffic is messy: rotating sessions, expired tokens, changing widget parameters, intermittent solver delays, and target pages that refresh without warning. For Automation developer, the safest rollout is to start with a narrow fixture, record every submitted task, and compare the solver response with the browser state that finally submits the form. That makes failures explainable instead of mysterious, especially when a target alternates between visible challenges, invisible checks, and server-side verification.

Evaluation Criteria

A developer guide should become a reusable integration module with typed configuration, bounded polling, structured errors, and a single place for API credentials. For developer integration work, the most useful scorecard combines technical acceptance with operational cost. A low nominal price is not enough if retries double the real cost per accepted token, and a fast median solve time is not enough if p95 latency stalls the queue. Track these criteria before you standardize the workflow:

  • The challenge subtype, sitekey, action, rqdata, blob, captchaId, or page URL used for each task.
  • Median and p95 solve time, separated by provider and target domain.
  • Accepted-token rate on the target page, not just successful API responses.
  • Retry count, timeout count, zero-balance incidents, and invalid-parameter errors.
  • The exact browser, proxy region, and user-agent that submitted the solved token.

Rollout Checklist

Before this guidance moves into a production job, build a small acceptance suite around the pages that matter most. Run it with a fixed browser profile, then repeat with the proxy and concurrency settings you expect in production. Keep the first release conservative: bounded polling, clear timeout handling, and a fallback path when the solver cannot return a usable answer. For developer integration, treat the code as a production pattern: timeouts, retries, logging, secret storage, and test fixtures matter as much as the solve request itself. That checklist keeps the article useful after the first copy-paste, because the integration is judged by end-to-end completion rather than by whether a code sample returned a string.

Monitoring Signals

Healthy CAPTCHA automation is observable. Log the task id, provider, challenge type, target host, queue time, solve time, final submit status, and normalized error code for every attempt. Review those logs in daily batches at first, then move to alerts once the baseline is stable. Sudden drops usually come from target-side changes: a new sitekey, a changed action name, a stricter hostname check, an added managed challenge, or a proxy pool that no longer matches the expected geography. When you can see those shifts quickly, provider switching becomes a controlled decision instead of a late-night rewrite.

Maintenance Cadence

Revisit the setup whenever the target UI changes, when the solver provider changes task names or pricing, or when benchmark data shows a sustained latency or solve-rate shift. Keep one known-good fixture for each CAPTCHA subtype and rerun it after dependency upgrades, browser updates, and proxy changes. If the article is used for vendor selection, repeat the same fixture across at least two providers before renewing a balance or migrating the whole pipeline. That habit keeps captcha solving python quick start work aligned with the real target behavior rather than with stale assumptions.

Comments are disabled for this article.

Related Posts

Developer Guides How to Use a CAPTCHA Solver with Playwright
Step-by-step guide to integrating a CAPTCHA solver into Playwright automation.

Step-by-step guide to integrating a CAPTCHA solver into Playwright automation. Covers re CAPTCHA v 2, h Captch...

May 06, 2026
Developer Guides How to Use a CAPTCHA Solver with Selenium
Step-by-step guide to integrating a CAPTCHA solver into Selenium automation.

Step-by-step guide to integrating a CAPTCHA solver into Selenium automation. Covers re CAPTCHA v 2, h Captcha,...

May 04, 2026
Developer Guides CAPTCHA Solver for Scrapy — Python Integration Guide
Complete guide to integrating a CAPTCHA solver into Scrapy spiders — covers middleware-based solving, Captcha AI API integration, handling re CAPTCHA and h Capt...

Complete guide to integrating a CAPTCHA solver into Scrapy spiders — covers middleware-based solving, Captcha...

May 06, 2026