Developer Tutorial9 min readhCaptcha & Enterprise

How to Solve hCaptcha & hCaptcha Enterprise in Python: Playwright & 2Captcha Guide

A complete technical walkthrough on bypassing hCaptcha standard challenges and Enterprise invisible verification using Python Playwright and the 2Captcha API. Includes sample code for sitekey extraction, rqdata handling, and token injection.

1. How hCaptcha Works & Why It Blocks Automation

hCaptcha is a widely adopted privacy-focused CAPTCHA provider deployed on Discord, Shopify stores, Epic Games, and Cloudflare-protected origins. Unlike basic visual text CAPTCHAs, hCaptcha challenges users with 3x3 image selection grids (identifying objects, animals, or orientation) and collects rich behavioral telemetry:

  • Mouse Dynamics & Gesture Telemetry: Tracks acceleration, curve smoothness, and hover dwell time before clicking the checkbox.
  • Browser Fingerprinting: Inspects Canvas rendering, WebGL context attributes, and audio API entropy to detect automated headless browsers.
  • Enterprise Risk Query Data (rqdata): In enterprise tiers, the target site generates a cryptographic risk token that must be echoed back inside the verification response.

Solving hCaptcha programmatically requires dispatching the challenge metadata to a specialized solver like 2Captcha, receiving a cryptographic validation token (P0_eyJ...), and injecting it into the DOM before submitting the form.

2. Installing Required Python Packages

Install the official 2captcha-python library and playwright:

pip install 2captcha-python playwright
playwright install chromium

3. Basic Task Dispatch via 2Captcha SDK

The TwoCaptcha SDK supports both standard hCaptcha and Enterprise deployments passing rqdata:

import os
from twocaptcha import TwoCaptcha

api_key = os.getenv("TWOCAPTCHA_API_KEY")
solver = TwoCaptcha(api_key)

try:
    print("Dispatching hCaptcha task to 2Captcha...")
    result = solver.hcaptcha(
        sitekey="a5f74b19-9e45-40e0-b45d-47ff91b7a630",
        url="https://target-portal.com/protected-page",
        # Optional parameters for hCaptcha Enterprise:
        # rqdata="captured_enterprise_rqdata_token",
    )
    token = result["code"]
    print("hCaptcha solved successfully!")
    print(f"Token: {token[:45]}...")
except Exception as e:
    print(f"Failed to solve hCaptcha: {e}")

4. Complete Playwright Pipeline with Token Injection

In production scraping or automation workflows, Playwright launches a browser, extracts the sitekey and any rqdata payload, waits for 2Captcha to solve the puzzle, and populates the hidden [name="h-captcha-response"] elements:

import asyncio
import os
from playwright.async_api import async_playwright
from twocaptcha import TwoCaptcha

API_KEY = os.getenv("TWOCAPTCHA_API_KEY")
solver = TwoCaptcha(API_KEY)
TARGET_URL = "https://example-protected.com/login"

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context()
        page = await context.new_page()

        print(f"Navigating to {TARGET_URL}...")
        await page.goto(TARGET_URL, wait_until="networkidle")

        # 1. Locate hCaptcha container & extract sitekey
        hcaptcha_el = await page.wait_for_selector("[data-sitekey]", timeout=10000)
        sitekey = await hcaptcha_el.get_attribute("data-sitekey")
        print(f"Detected hCaptcha with sitekey: {sitekey}")

        # 2. Extract rqdata if present (hCaptcha Enterprise)
        rqdata = await page.evaluate("""() => {
            const el = document.querySelector("[data-rqdata]");
            return el ? el.getAttribute("data-rqdata") : null;
        }""")

        # 3. Request solution from 2Captcha
        print("Sending hCaptcha challenge to 2Captcha API...")
        solve_params = {"sitekey": sitekey, "url": TARGET_URL}
        if rqdata:
            solve_params["rqdata"] = rqdata

        result = await asyncio.to_thread(solver.hcaptcha, **solve_params)
        token = result["code"]
        print(f"Received solution token: {token[:40]}...")

        # 4. Inject token into h-captcha-response & g-recaptcha-response textareas
        await page.evaluate("""(solvedToken) => {
            const inputs = document.querySelectorAll('[name="h-captcha-response"], [name="g-recaptcha-response"]');
            inputs.forEach(el => {
                el.value = solvedToken;
                el.innerHTML = solvedToken;
                el.dispatchEvent(new Event("change", { bubbles: true }));
            });
            // Trigger client-side JavaScript callback if defined
            if (window.hcaptcha && typeof window.hcaptcha.execute === "function") {
                const container = document.querySelector("[data-sitekey]");
                const callbackName = container ? container.getAttribute("data-callback") : null;
                if (callbackName && typeof window[callbackName] === "function") {
                    window[callbackName](solvedToken);
                }
            }
        }""", token)

        # 5. Submit form
        print("Submitting protected form...")
        await page.click('button[type="submit"]')
        await page.wait_for_load_state("networkidle")
        print("Successfully bypassed hCaptcha!")
        await browser.close()

if __name__ == "__main__":
    asyncio.run(main())

5. Key Steps for Successful hCaptcha Bypass

  1. Extract the Correct Sitekey: Inspect the DOM for an element containing class="h-captcha" or data-sitekey. The sitekey is a UUID format string (e.g. a5f74b19-9e45-40e0-b45d-47ff91b7a630).
  2. Pass rqdata for Enterprise: On high-security sites, inspect network requests to /getcaptcha. If an rqdata parameter is exchanged, pass it into solver.hcaptcha(..., rqdata=...) to avoid token rejection.
  3. Trigger Client Callbacks: Many modern React or Vue apps do not have a traditional submit button; they rely on data-callback. The Playwright snippet automatically invokes window[callbackName](solvedToken) when defined.

6. Why 2Captcha is Rated #1 for hCaptcha Resolution

2Captcha hCaptcha Benchmark Telemetry

Rank #1 Overall
  • Average Solving Speed: 9.4 seconds (AI-accelerated human worker pool)
  • Pass Rate: 99.7% first-attempt token acceptance across Discord & Shopify
  • Pricing: $1.00 per 1,000 solves with true Pay-As-You-Go ($0.001 per challenge)
  • Enterprise Support: Full support for hCaptcha Enterprise, rqdata, and custom proxy routing
Get 2Captcha API Key ($1.00/1k) →