Requirements
- Python 3.8+
- Playwright installed
playwright-captchalibrary- A 2Captcha account and API key
Install everything:
pip install playwright playwright-captcha 2captcha-python python-dotenv
playwright install chromium
Set up your API key in a .env file:
TWO_CAPTCHA_API_KEY=your_api_key_here
How the API Solver Works
The 2Captcha service receives your captcha challenge (sitekey + page URL), solves it using real humans or AI, and returns a token. You inject that token into the page and submit the form. The whole process takes 10–30 seconds.
playwright-captcha handles all of this automatically — finding the sitekey, sending it to 2Captcha, injecting the response, and confirming success.
Solving reCAPTCHA v2
reCAPTCHA v2 is embedded in a container on the page. Find the selector of the reCAPTCHA container on your target page and pass it to the solver — in this example we use #g-recaptcha from the demo page.
import asyncio
import logging
import os
from dotenv import load_dotenv
from playwright.async_api import async_playwright
from twocaptcha import AsyncTwoCaptcha
from playwright_captcha import CaptchaType, TwoCaptchaSolver, FrameworkType
logging.basicConfig(level='INFO')
load_dotenv()
TWO_CAPTCHA_API_KEY = os.getenv('TWO_CAPTCHA_API_KEY')
async def solve_recaptcha_v2():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=False)
page = await browser.new_page()
framework = FrameworkType.PLAYWRIGHT
# Create solver BEFORE navigating to the page
async with TwoCaptchaSolver(
framework=framework,
page=page,
async_two_captcha_client=AsyncTwoCaptcha(TWO_CAPTCHA_API_KEY)
) as solver:
await page.goto('https://2captcha.com/demo/recaptcha-v2')
await asyncio.sleep(5)
# Find the reCAPTCHA container
recaptcha_container = page.locator('#g-recaptcha')
await recaptcha_container.wait_for()
# Solve it
await solver.solve_captcha(
page=page,
captcha_container=recaptcha_container,
captcha_type=CaptchaType.RECAPTCHA_V2,
)
# Submit the form
submit_button = page.locator('//button[@data-action="demo_action"]')
await submit_button.wait_for()
await submit_button.click()
await asyncio.sleep(5)
try:
await page.locator('//p[text()="Captcha is passed successfully!"]').wait_for(timeout=10000)
logging.info('reCAPTCHA v2 solved successfully!')
except Exception as e:
logging.error(f'Failed: {e}')
asyncio.run(solve_recaptcha_v2())
Solving reCAPTCHA v3
reCAPTCHA v3 is invisible — there’s no container to find. The library detects it from the page’s JavaScript and handles everything automatically.
import asyncio
import logging
import os
from dotenv import load_dotenv
from playwright.async_api import async_playwright
from twocaptcha import AsyncTwoCaptcha
from playwright_captcha import CaptchaType, TwoCaptchaSolver, FrameworkType
logging.basicConfig(level='INFO')
load_dotenv()
TWO_CAPTCHA_API_KEY = os.getenv('TWO_CAPTCHA_API_KEY')
async def solve_recaptcha_v3():
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
page = await browser.new_page()
framework = FrameworkType.PLAYWRIGHT
# Create solver BEFORE navigating to the page
async with TwoCaptchaSolver(
framework=framework,
page=page,
async_two_captcha_client=AsyncTwoCaptcha(TWO_CAPTCHA_API_KEY)
) as solver:
await page.goto('https://2captcha.com/demo/recaptcha-v3')
await asyncio.sleep(5)
# v3 is invisible — pass the full page as container
await solver.solve_captcha(
page=page,
captcha_container=page,
captcha_type=CaptchaType.RECAPTCHA_V3,
)
# Submit the form
submit_button = page.locator('//button[@data-action="demo_action"]')
await submit_button.wait_for()
await submit_button.click()
await asyncio.sleep(5)
try:
await page.locator('//p[text()="Captcha is passed successfully!"]').wait_for(timeout=10000)
logging.info('reCAPTCHA v3 solved successfully!')
except Exception as e:
logging.error(f'Failed: {e}')
asyncio.run(solve_recaptcha_v3())
Using Stealth Browsers for Better Results
Standard Playwright is often detected by Google’s bot analysis. For higher success rates — especially with reCAPTCHA v3 which relies heavily on browser signals — use a stealth browser. Popular options include Camoufox, Patchright, AdsPower, Dolphin Anty, Multilogin, and GoLogin.
This guide covers Camoufox and Patchright since they’re free and integrate directly with Playwright.
Option A: Patchright
Patchright is a patched version of Playwright that removes headless detection signals.
pip install patchright
patchright install chromium
from patchright.async_api import async_playwright
from playwright_captcha import FrameworkType
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(channel="chrome", headless=True)
context = await browser.new_context()
page = await context.new_page()
framework = FrameworkType.PATCHRIGHT
# ... rest of your code
Option B: Camoufox
Camoufox is a Firefox-based stealth browser with advanced fingerprinting spoofing.
pip install camoufox
camoufox fetch
from camoufox import AsyncCamoufox
from playwright_captcha.utils.camoufox_add_init_script.add_init_script import get_addon_path
from playwright_captcha import FrameworkType
import os
ADDON_PATH = get_addon_path()
async with AsyncCamoufox(
headless=True,
geoip=True,
humanize=True,
main_world_eval=True, # required for playwright-captcha
addons=[os.path.abspath(ADDON_PATH)] # required for playwright-captcha
) as browser:
context = await browser.new_context()
page = await context.new_page()
framework = FrameworkType.CAMOUFOX
# ... rest of your code
Note: Camoufox has a known issue with
add_init_script. Theplaywright-captchapackage includes a built-in workaround — just addmain_world_eval=Trueand the addon path as shown above.
Solver Configuration Options
solver = TwoCaptchaSolver(
framework=framework,
page=page,
async_two_captcha_client=captcha_client,
max_attempts=3, # retry up to 3 times
attempt_delay=10, # wait 10 seconds between attempts
sitekey='your_sitekey_here' # optional: provide manually if auto-detection fails
)
v2 vs v3: Key Differences
| reCAPTCHA v2 | reCAPTCHA v3 | |
|---|---|---|
| Visible to user | Yes (checkbox) | No (invisible) |
| Image puzzle | Sometimes | Never |
| How it’s solved | Token injection | Score-based token injection |
| Harder with standard Playwright | Yes | Very much so |
| Recommended browser | Patchright or Camoufox | Camoufox (score matters more) |
Common Issues and Fixes
reCAPTCHA v3 score too low / keeps failing Switch to Camoufox — it spoofs browser fingerprints much better than standard Playwright, which directly affects the v3 score Google assigns.
Sitekey not detected automatically
Pass it manually via sitekey='your_sitekey' in the solver constructor. Find it in the page source — look for data-sitekey in the reCAPTCHA widget HTML, or search for grecaptcha.execute in the page’s JavaScript for v3.
add_init_script error with Camoufox
Add main_world_eval=True and the addon path when creating the Camoufox instance. The playwright-captcha package handles the rest automatically.
Full Project on GitHub
The playwright-captcha library supports:
- reCAPTCHA v2 and v3
- Cloudflare Turnstile (widget + interstitial)
- Multiple solving services (2Captcha, TenCaptcha, more coming)
Check it out and leave a star if it helped: github.com/techinz/playwright-captcha