DEV Community

Bob
Bob

Posted on • Originally published at capbypass.pro

Captcha solving with Playwright

Playwright drives a real browser, so people expect captchas to just work - but reCAPTCHA and hCaptcha still score the session and block automated traffic. This post keeps your Playwright flow and offloads only the captcha: detect it on the page, get a token from CapBypass over HTTP, inject it, and submit.


why playwright still hits captchas

A real browser clears the "can it run JavaScript" bar, but reCAPTCHA v3 and hCaptcha go further - they score behaviour and device signals. Automated Playwright sessions often score low enough to be challenged or silently rejected. You still end up needing a token the site will accept.

Rather than fight the in-page widget, solve it out of band and drop the token into the page Playwright already controls.


detecting the challenge on the page

Read the site key straight out of the DOM:

async def get_recaptcha_key(page):
    el = await page.query_selector("[data-sitekey]")
    return await el.get_attribute("data-sitekey") if el else None
Enter fullscreen mode Exit fullscreen mode

If a key comes back, the page is gated and you solve before submitting.


solving via the api

Your Playwright script calls the CapBypass HTTP API for the token - no second browser, just a request. Use the Python SDK:

import os
from capbypass import CapBypass

solver = CapBypass(api_key=os.environ["CAPBYPASS_API_KEY"])

def solve(url: str, key: str) -> str:
    result = solver.solve({
        "type": "ReCaptchaV2Task",
        "websiteURL": url,
        "websiteKey": key,
        "proxy": "host:port:user:pass",
    })
    return result["solution"]["gRecaptchaResponse"]
Enter fullscreen mode Exit fullscreen mode

injecting the token into the page

reCAPTCHA reads its answer from a hidden <textarea name="g-recaptcha-response">. Set it via page.evaluate, then submit the form as a user would:

async def pass_recaptcha(page, url):
    key = await get_recaptcha_key(page)
    token = solve(url, key)

    await page.evaluate(
        """(t) => {
            let ta = document.querySelector('textarea[name="g-recaptcha-response"]');
            if (!ta) {
                ta = document.createElement('textarea');
                ta.name = 'g-recaptcha-response';
                ta.style.display = 'none';
                document.body.appendChild(ta);
            }
            ta.value = t;
        }""",
        token,
    )

    await page.click("button[type=submit]")
Enter fullscreen mode Exit fullscreen mode

For an invisible or callback-driven widget you may need to call the site's JS callback with the token instead of clicking submit - inspect what grecaptcha.render registered.


Playwright token injection pipeline: solve via CapBypass HTTP, then page.evaluate sets textarea[name=g-recaptcha-response].value, then page.click submits the form with a valid token.

hcaptcha and v3

Same shape, different field/task:

  • hCaptcha: the token goes into textarea[name="h-captcha-response"]; solve with HCaptchaTaskProxyless.
  • reCAPTCHA v3: there is no checkbox - the page calls grecaptcha.execute(key, {action}). Solve with ReCaptchaV3Task and the matching pageAction, then feed the token wherever the page sends it. See the reCAPTCHA v3 docs.

Bonus: +5% credits on every top-up

New to CapBypass? Apply code WELCOME_2026 at checkout for an extra 5% in credits on every top-up, with no minimum and no expiry. Redeem it on the top-up page and put it toward your first ReCaptchaV2Task solves.


things that go wrong

  • Token set but nothing happens. The widget uses a JS callback, not a plain submit. Call the registered callback with the token instead of clicking.
  • Low v3 score even from a browser. Playwright sessions can score low; a clean proxy on the solve helps. See why your reCAPTCHA v3 score is low.
  • Stale token. Solve right before injecting; tokens expire in about 2 minutes.

faq

Does CapBypass run the browser for me?
No - you run Playwright. CapBypass solves the captcha over HTTP and returns a token; you inject it into your own page. It is a plain API call from inside your script.

Where do I put the token in Playwright?
For reCAPTCHA, into textarea[name="g-recaptcha-response"] via page.evaluate, then submit. For hCaptcha use h-captcha-response.

Why is my session still blocked with a valid token?
On reCAPTCHA v3 a valid token can still score below the site's threshold. Solve through a clean proxy and match the pageAction.

Playwright or just the HTTP API?
If the site works without a browser, the plain HTTP approach is cheaper and faster. Use Playwright only when the page genuinely needs a rendered session for the rest of the flow.


Originally published on capbypass.pro. CapBypass is an AI-powered captcha-solving API for reCAPTCHA, hCaptcha, Cloudflare Turnstile and AWS WAF.

Top comments (0)