Skip to content

Python Module ​

Uses Python to automatically solve captchas.
Supports image clicking, slider dragging, and other captcha types.
Can detect the captcha type on the page automatically.

Latest Version ​

VersionChangesDownload
0.4Global updatePyPI * Download
0.3Added AWS WAF (Amazon)Download
0.2Fix hcapDownload
0.1Initial releaseDownload

Installation ​

The module is published on PyPI:

pip install capguru
playwright install chromium

Update to the latest version:

pip install -U capguru

The import stays the same:

python
from captcha_solver import CaptchaSolver, CapGuruFatalError
Installation without pip

Download the archive from the version table and copy the captcha_solver folder into your project, next to your script.
Install the dependencies manually:

pip install playwright httpx Pillow
playwright install chromium

If the module is installed via pip, do not keep a captcha_solver folder next to your script: Python will use that folder instead of the installed version.

Usage ​

Import CaptchaSolver from the package.
Create the solver before navigating to the page with the captcha and call await solver.setup().
Then open the page and call await solver.auto() � the module will find the captcha and solve it.
If you know the captcha type in advance, you can call the specific method directly.

python
solver = CaptchaSolver(page=page, api_key='YOUR_KEY', debug=True)
await solver.setup()

await page.goto('https://site.com/cap')

kind = await solver.auto(timeout=30)
print('Captcha:', kind or 'not found')

Why the solver is created before navigation

When created, the solver starts capturing the captcha images loaded by the browser and switches hCaptcha to English. If you create it after page.goto(), images from the first load will be missed and hCaptcha may stay in the site's language.

Examples ​

py
# pip install playwright playwright-stealth httpx Pillow
# playwright install chrome

import asyncio
from playwright.async_api import async_playwright
from playwright_stealth import Stealth
from captcha_solver import CaptchaSolver, CapGuruFatalError


async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=False,
            channel="chrome",
            args=["--disable-blink-features=AutomationControlled"],
        )
        page = await browser.new_page()
        await Stealth().apply_stealth_async(page)

        solver = CaptchaSolver(
            page=page,
            api_key='YOUR_KEY',
            debug=True,
            attempts=5,
        )
        await solver.setup()

        await page.goto('https://site.com/cap')

        try:
            kind = await solver.auto(timeout=30)
            print('Captcha:', kind or 'not found')
        except CapGuruFatalError as e:
            print('API key or balance problem:', e)

        await browser.close()

asyncio.run(main())
py
# pip install playwright httpx Pillow
# playwright install chromium

import asyncio
from playwright.async_api import async_playwright
from captcha_solver import CaptchaSolver, CapGuruFatalError


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

        solver = CaptchaSolver(
            page=page,
            api_key='YOUR_KEY',
            debug=True,
            attempts=5,
        )
        await solver.setup()

        await page.goto('https://site.com/cap')

        try:
            kind = await solver.auto(timeout=30)
            print('Captcha:', kind or 'not found')
        except CapGuruFatalError as e:
            print('API key or balance problem:', e)

        await browser.close()

asyncio.run(main())
py
# pip install playwright httpx Pillow
# playwright install firefox

import asyncio
from playwright.async_api import async_playwright
from captcha_solver import CaptchaSolver, CapGuruFatalError


async def main():
    async with async_playwright() as p:
        browser = await p.firefox.launch(headless=False)
        page = await browser.new_page()

        solver = CaptchaSolver(
            page=page,
            api_key='YOUR_KEY',
            debug=True,
            attempts=5,
        )
        await solver.setup()

        await page.goto('https://site.com/cap')

        try:
            kind = await solver.auto(timeout=30)
            print('Captcha:', kind or 'not found')
        except CapGuruFatalError as e:
            print('API key or balance problem:', e)

        await browser.close()

asyncio.run(main())
py
# pip install undetected-chromedriver playwright httpx Pillow
# Chrome browser must be installed

import asyncio
import undetected_chromedriver as uc
from playwright.async_api import async_playwright
from captcha_solver import CaptchaSolver, CapGuruFatalError


async def main():
    driver = uc.Chrome(headless=False)
    try:
        address = driver.capabilities['goog:chromeOptions']['debuggerAddress']
        async with async_playwright() as p:
            browser = await p.chromium.connect_over_cdp(f'http://{address}')
            page = browser.contexts[0].pages[0]

            solver = CaptchaSolver(
                page=page,
                api_key='YOUR_KEY',
                debug=True,
                attempts=5,
            )
            await solver.setup()

            await asyncio.to_thread(driver.get, 'https://site.com/cap')

            try:
                kind = await solver.auto(timeout=30)
                print('Captcha:', kind or 'not found')
            except CapGuruFatalError as e:
                print('API key or balance problem:', e)
    finally:
        driver.quit()

asyncio.run(main())
py
# pip install selenium playwright httpx Pillow
# Chrome browser and chromedriver must be installed

import asyncio
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from playwright.async_api import async_playwright
from captcha_solver import CaptchaSolver, CapGuruFatalError


async def main():
    options = webdriver.ChromeOptions()
    # options.add_argument('--headless=new')
    service = Service()  # Service('/path/to/chromedriver')
    driver = webdriver.Chrome(service=service, options=options)
    try:
        address = driver.capabilities['goog:chromeOptions']['debuggerAddress']
        async with async_playwright() as p:
            browser = await p.chromium.connect_over_cdp(f'http://{address}')
            page = browser.contexts[0].pages[0]

            solver = CaptchaSolver(
                page=page,
                api_key='YOUR_KEY',
                debug=True,
                attempts=5,
            )
            await solver.setup()

            await asyncio.to_thread(driver.get, 'https://site.com/cap')

            try:
                kind = await solver.auto(timeout=30)
                print('Captcha:', kind or 'not found')
            except CapGuruFatalError as e:
                print('API key or balance problem:', e)
    finally:
        driver.quit()

asyncio.run(main())
py
# pip install selenium-wire undetected-chromedriver playwright httpx Pillow
# Chrome browser must be installed

import asyncio
import seleniumwire.undetected_chromedriver as uc
from playwright.async_api import async_playwright
from captcha_solver import CaptchaSolver, CapGuruFatalError


async def main():
    options = uc.ChromeOptions()
    # options.add_argument('--headless=new')
    driver = uc.Chrome(options=options, headless=False)
    try:
        address = driver.capabilities['goog:chromeOptions']['debuggerAddress']
        async with async_playwright() as p:
            browser = await p.chromium.connect_over_cdp(f'http://{address}')
            page = browser.contexts[0].pages[0]

            solver = CaptchaSolver(
                page=page,
                api_key='YOUR_KEY',
                debug=True,
                attempts=5,
            )
            await solver.setup()

            await asyncio.to_thread(driver.get, 'https://site.com/cap')

            try:
                kind = await solver.auto(timeout=30)
                print('Captcha:', kind or 'not found')
            except CapGuruFatalError as e:
                print('API key or balance problem:', e)
    finally:
        driver.quit()

asyncio.run(main())

The Chrome, Chromedriver and Seleniumwire examples launch the browser with Selenium and connect the solver to the same browser through Playwright. They work with Chrome only and require Python 3.9+.

Methods ​

Automatic:

         await solver.auto(timeout=30)   # find and solve the captcha, returns its type or None
         await solver.detect()           # only detect the type, without solving
         await solver.setup()            # preparation, call before page.goto()

For a specific type:

         await solver.solve_recaptcha2()
         await solver.solve_hcaptcha()
         await solver.solve_other()
         await solver.solve_geetest()
         await solver.solve_funcaptcha()
         await solver.solve_tiktok()
         await solver.solve_aws()

auto() and detect() return the captcha type:

ValueCaptcha
recaptcha2reCAPTCHA v2
hcaptchahCaptcha
yandexOther
geetestGeeTest v3 / v4
funcaptchaFunCaptcha (Arkose Labs)
tiktokTikTok
awsAWS WAF
NoneNo captcha found within the timeout

Supported Captchas
​


reCaptcha2FunCaptchaTikTokGeeTesthCaptchaAWS WAFOther
YesYesYesYesYesYesYes

Parameters ​


ParameterTypeDefaultDescription
pagePage�Page containing the captcha
api_keystr�Cap.Guru API key
attemptsint5Max number of attempts
debugboolFalseEnable debug logging
selectorstr''CSS selector of the captcha container

auto() parameters:

ParameterTypeDefaultDescription
timeoutfloat30How many seconds to wait for a captcha to appear
pollfloat0.5How often to check the page, in seconds

Error Handling ​

An invalid API key or zero balance raises CapGuruFatalError � the module stops retrying immediately.
If the captcha could not be solved after all attempts, RuntimeError is raised.
CapGuruFatalError is a subclass of RuntimeError, so catch it first:

python
from captcha_solver import CaptchaSolver, CapGuruFatalError

try:
    kind = await solver.auto(timeout=30)
    print('Captcha:', kind or 'not found')
except CapGuruFatalError as e:
    print('API key or balance problem:', e)
except RuntimeError as e:
    if 'ERROR_CAPTCHA_UNSOLVABLE' in str(e):
        print('Captcha was not solved after all attempts')