Metadata-Version: 2.4
Name: playwright-captcha-solver
Version: 1.0.0
Summary: Simple and lightweight Python SDK for Playwright that facilitates the automation of text captcha and reCaptcha in enterprise automation workflows using Death By Captcha.
Author: DOM Tasks
License: Copyright © 2026 DOM Tasks.
        
        LICENSE GRANT
        
        Subject to this License, you are granted permission to:
        
            ✓ Install and use this software.
        
            ✓ Use this software in personal projects and in commercial or internal business applications developed by you or your organization.
        
            ✓ Modify this software solely for your own internal use.
        
        
        You may NOT:
        
        
            ✗ Redistribute this software, whether modified or unmodified.
        
            ✗ Publish or make available modified versions of this software to any third party.
        
            ✗ Sell, sublicense, rent, lease, assign, or otherwise transfer this software or any modified version of it.
        
            ✗ Remove, alter, or obscure any copyright notices, trademarks, branding, attribution, or license notices contained in the software.
        
            ✗ Represent modified versions as the original software.
        
            ✗ Use the software in violation of applicable laws.
        
            ✗ Use this software or any substantial portion of it to develop, distribute, or commercialize a competing software library, SDK, or similar product.
        
        
        OWNERSHIP
        
            No ownership rights are transferred under this License. Ownership of the software and all intellectual property rights remain with the copyright holder.
        
            All rights not expressly granted under this License are reserved by the copyright holder.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
Project-URL: Homepage, https://github.com/domtasks/playwright-captcha-solver-python
Project-URL: Documentation, https://github.com/domtasks/playwright-captcha-solver-python
Project-URL: Repository, https://github.com/domtasks/playwright-captcha-solver-python
Project-URL: Issues, https://github.com/domtasks/playwright-captcha-solver-python/issues
Keywords: playwright,captcha,recaptcha,captcha solver,browser automation,automation,deathbycaptcha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.28
Requires-Dist: playwright>=1.54
Dynamic: license-file

# DOM Tasks

Automate text CAPTCHA and reCAPTCHA in Playwright with Python.

```python
result = await solver.solve(
    RecaptchaChallenge(
        page=page,
    )
)
```

✔ **No** polling loops

✔ **No** API requests

✔ **No** token injection

✔ **No** balance fetching

✔ **No** manual retry logic

## Getting Started

DOM Tasks 'playwright-captcha-solver' integrates with DeathByCaptcha to solve text CAPTCHAs and reCAPTCHA.

Before you begin: 

👉 **[Create a DeathByCaptcha account](https://deathbycaptcha.com/register?refid=6184513722b)**. When you're ready to solve captchas, simply **[add credits to it](https://deathbycaptcha.com/user-pay?refid=1237486458a)**; packages start at just **$5**.

The examples throughout this documentation use DeathByCaptcha and require the API credentials you'll obtain after registering.

Install the package:

```Bash
pip install playwright-captcha-solver
```

Install Playwright browsers:

playwright install

If you haven't installed Playwright yet:

```Bash
pip install playwright
```
<br>
<br>

> # 🚀 Start Here
>
> Don't scroll yet.
>
> Choose the guide that matches your use case.
>
> ### Step 1 - I want to...
>
>- 👉 **[Solve a text captcha](#solving-text-captcha)**
>- 👉 **[Solve a reCAPTCHA v2](#solving-recaptcha-v2)**
>
> Each guide walks through authentication, solving the challenge, viewing the result, and handling incorrect captchas.
>
<br><br><br><br>

---
## Solving Text captcha

### Step 2 - I want to authenticate with...

- 👉 **[DBC Username & Password](#username-and-password-authentication)**
- 👉 **[DBC Authtoken (2FA)](#authtoken-authentication)**


### Username and password authentication

Authenticate using your DeathByCaptcha account credentials.

```python
from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    Credentials,
)

solver = CaptchaSolver(
    CaptchaSolverOptions(
        auth=Credentials(
            username=os.getenv("DBC_USERNAME"),
            password=os.getenv("DBC_PASSWORD"),
        )
    )
)
```
**`Credentials:`** Authenticates using your DeathByCaptcha username and password.

**`username:`** Your DeathByCaptcha account username.

**`password:`** Your DeathByCaptcha account password.

We recommend storing credentials as environment variables.


### Step 3 - Solve captcha

- 👉 **[Solve text captcha](#solving-text-captchas)**

___

### Authtoken authentication

**a) Setting up 2FA (authtoken) with DeathByCaptcha**

1. **[Log in](https://deathbycaptcha.com/login?refid=6184513722b)** to your account
2. Go to `User Settings` at the bottom of the page
3. Click on `Authentication options`
4. Check the box "Enable this to use 2FA authentication" and click on SUBMIT
5. Download Google Authenticator app, open it and click on the '+' button to add a new entry.
6. Scan the QR code with your phone through the app and insert the code from the app into 'Verification code' field on the site.
7. Copy and save your "Authentication Token" as an environment variable in your code and finally check the box "Enable this to use the token instead of User/Password combination" on the site. Authentication Token is ~156 characters long.

**Sample token:**
```Bash
CQ6dd4DzLk5y830M2S16TnNEAqetNp2VmAPPx6CjM5wxRYpS0zm0CTMH38iBKfC3qf4tB9d2XIpzI184ZJv0G2RMUUcHi60372MRxUkE5A71bDopA3aQum2029LlLwX4R61hwr7fR51p6zRADdhT9u07e9v6
```

**b) Initialize the solver:**

```python
from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    AuthToken,
)

solver = CaptchaSolver(
    CaptchaSolverOptions(
        auth=AuthToken(
            authtoken=os.getenv("DBC_AUTHTOKEN"),
        )
    )
)
```
**`AuthToken:`** Authenticates using your DeathByCaptcha Authentication Token.

**`authtoken:`** Your DeathByCaptcha Authentication Token.

We recommend storing it as an environment variable instead of hardcoding it into your application.



## Solving Text Captchas

Use the **`solve()`** method to solve the challenge currently displayed on the page.

```python
result = await solver.solve(
    ImageChallenge(
        page=page,
        captcha=captcha_locator,
        input=input_locator,
    )
)
```
**`ImageChallenge:`** Represents an image CAPTCHA challenge.

**`page:`** A Playwright Page instance.

Example:

```python
page = await browser.new_page()
```
**`captcha:`** A Playwright Locator pointing to the CAPTCHA image.

Supported elements include:

- `<img>`
- `<canvas>`
- `<svg>`
- Container elements wrapping the CAPTCHA

Example:

```python
captcha_locator = page.locator("#captcha")
```
**`input:`** A Playwright Locator representing the input field where the solved CAPTCHA text should be entered.

Example:

```python
input_locator = page.locator("#captcha-input")
```

### Captcha solution metadata

The **`solve()`** method returns a SolveResult.

```python
result = await solver.solve(
    ImageChallenge(
        page=page,
        captcha=captcha_locator,
        input=input_locator,
    )
)

print(result)
```

Example output:

```Bash
SolveResult(
    success=True,
    challenge="image",
    duration=4124,
    id="235368206",
    balance=10.081007,
)
```

The returned object contains:

**`success`:** Whether the operation completed successfully. If your target website still rejects the submitted CAPTCHA after automation continues, you should report it using report().

**`challenge`:** The type of challenge that was solved.

**`duration`:** Total execution time in milliseconds.

**`id`:** The CAPTCHA identifier assigned by DeathByCaptcha.

**`balance`:** Your remaining DeathByCaptcha balance after solving the challenge.


### Reporting incorrect captchas:

Incorrect solutions can be reported to DeathByCaptcha so your account is credited appropriately.

```python
result = await solver.solve(
    ImageChallenge(
        page=page,
        captcha=captcha_locator,
        input=input_locator,
    )
)

await solver.report(result.id)
```

Your automation should determine whether the CAPTCHA was accepted by the target website.

**For example, your application may:**

Detect a validation message.
Wait for a successful page navigation.
Solve the captcha with the `solve()` function.
Submit the form.
Inspect for a warning if captcha was incorrect.

If the CAPTCHA was solved incorrectly, report it using:

```python 
await solver.report(result.id)
```

Please use this feature responsibly. Excessive reporting of correctly solved CAPTCHAs may result in account restrictions.

## Text captcha full code example

Install dependencies:

```Bash
pip install playwright
pip install python-dotenv
pip install playwright-captcha-solver
playwright install
```

```python
import asyncio
import os

from dotenv import load_dotenv
from playwright.async_api import async_playwright

from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    Credentials,
    ImageChallenge,
)

load_dotenv()

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

        await page.goto(
            "https://captcha.com/demos/features/captcha-demo.aspx"
        )

        captcha_locator = page.locator("#demoCaptcha_CaptchaImage")
        input_locator = page.locator("#captchaCode")

        async with CaptchaSolver(
            CaptchaSolverOptions(
                auth=Credentials(
                    username=os.getenv("DBC_USERNAME"),
                    password=os.getenv("DBC_PASSWORD"),
                )
            )
        ) as solver:

            result = await solver.solve(
                ImageChallenge(
                    page=page,
                    captcha=captcha_locator,
                    input=input_locator,
                )
            )

            print(result)

            # await solver.report(result.id)

        await page.click("#validateCaptchaButton")

        await asyncio.sleep(5)
        await browser.close()

asyncio.run(main())
```

### Next Step — Error handling:

- 👉 [Continue to the Error Handling section after the reCAPTCHA guide](#error-handling)

<br><br><br><br>

# Solving reCAPTCHA v2

### Step 2 - I want to authenticate with...

- 👉 **[DBC Username & Password](#username-password-authentication)**
- 👉 **[DBC Authtoken (2FA)](#authtoken-authentication-method)**


## Username password authentication

Authenticate using your DeathByCaptcha account credentials.

```python
from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    Credentials,
)

solver = CaptchaSolver(
    CaptchaSolverOptions(
        auth=Credentials(
            username=os.getenv("DBC_USERNAME"),
            password=os.getenv("DBC_PASSWORD"),
        )
    )
)
```
**`Credentials:`** Authenticate using your DeathByCaptcha username and password.

**`username:`** Your DeathByCaptcha account username.

**`password:`** Your DeathByCaptcha account password.

We recommend storing credentials as environment variables.

### Step 3 - Solve reCAPTCHAS

- 👉 **[Automate reCAPTCHA v2](#solving-recaptchas-v2)**

___

## Authtoken authentication method

**a) Setting up 2FA (authtoken) with DeathByCaptcha**

1. **[Log in](https://deathbycaptcha.com/login?refid=6184513722b)** to your account
2. Go to `User Settings` at the bottom of the page
3. Click on `Authentication options`
4. Check the box "Enable this to use 2FA authentication" and click on SUBMIT
5. Download Google Authenticator app, open it and click on the '+' button to add a new entry.
6. Scan the QR code with your phone through the app and insert the code from the app into 'Verification code' field on the site.
7. Copy and save your "Authentication Token" as an environment variable in your code and finally check the box "Enable this to use the token instead of User/Password combination" on the site. Authentication Token is ~156 characters long.

**Sample token:**
```Bash
CQ6dd4DzLk5y830M2S16TnNEAqetNp2VmAPPx6CjM5wxRYpS0zm0CTMH38iBKfC3qf4tB9d2XIpzI184ZJv0G2RMUUcHi60372MRxUkE5A71bDopA3aQum2029LlLwX4R61hwr7fR51p6zRADdhT9u07e9v6
```
**b) Initialize solver with token created:**

```python
from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    AuthToken,
)

solver = CaptchaSolver(
    CaptchaSolverOptions(
        auth=AuthToken(
            authtoken=os.getenv("DBC_AUTHTOKEN"),
        )
    )
)
```

**`AuthToken:`** Authenticate using your DeathByCaptcha Authentication Token.

**`authtoken:`** Your DeathByCaptcha Authentication Token.

We recommend storing it as an environment variable instead of hardcoding it.

## Solving reCAPTCHAs v2

```python
result = await solver.solve(
    RecaptchaChallenge(
        page=page,
        # proxy="http://username:password@proxy-provider.com"
    )
)
```

**`RecaptchaChallenge:`** Represents a Google reCAPTCHA v2 challenge.

**`page:`** A Playwright Page instance.

Example:

```python
page = await browser.new_page()
```

**`proxy:`** (Optional) An HTTP proxy string.

Example:

```python
proxy="http://username:password@proxy-provider.com"
```

If omitted, the current network connection is used.

---

### Captcha solution metadata

The **`solve()`** method returns a SolveResult.

```python
result = await solver.solve(
    RecaptchaChallenge(
        page=page,
    )
)

print(result)
```

Example output:

```Bash
SolveResult(
    success=True,
    challenge="recaptcha",
    duration=14124,
    id="235368206",
    balance=10.091007,
)
```

The returned object contains:

**`success:`** Whether the operation completed successfully.

**`challenge:`** The challenge type that was solved.

**`duration:`** Total execution time in milliseconds.

**`id:`** DeathByCaptcha challenge identifier.

**`balance:`** Your remaining DeathByCaptcha account balance after solving the challenge.

## ReCAPTCHA full code example

**Install dependencies:**

```Bash
pip install playwright
pip install python-dotenv
pip install playwright-captcha-solver

playwright install
```

```python
import asyncio
import os

from dotenv import load_dotenv
from playwright.async_api import async_playwright

from captcha_solver import (
    CaptchaSolver,
    CaptchaSolverOptions,
    Credentials,
    RecaptchaChallenge,
)

load_dotenv()

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

        await page.goto(
            "https://www.google.com/recaptcha/api2/demo"
        )

        async with CaptchaSolver(
            CaptchaSolverOptions(
                auth=Credentials(
                    username=os.getenv("DBC_USERNAME"),
                    password=os.getenv("DBC_PASSWORD"),
                )
            )
        ) as solver:

            result = await solver.solve(
                RecaptchaChallenge(
                    page=page,
                )
            )

            print(result)

        await page.click("#recaptcha-demo-submit")

        await asyncio.sleep(5)
        await browser.close()

asyncio.run(main())
```

## Error Handling


The SDK throws typed errors instead of generic `Error` objects.

#### Possible Errors

| Error                 | Description                                                |
| --------------------- | ---------------------------------------------------------- |
| NetworkError          | Network error, conexion lost.                              |
| TimeoutError          | The operation exceeded the configured timeout.             |
| CaptchaSolverError    | The provider returned an error.                            |



## Design Principles

DOM Tasks follows a minimal design philosophy.

- You own the browser.
    
- You own the Playwright `Page`.

- You own the automation workflow.

- The SDK performs one operation and immediately returns control.

- The SDK never creates browser instances.

- The SDK never manages browser lifecycle.

- The SDK never hides Playwright APIs.
    
This allows the SDK to integrate naturally into existing Playwright automation without imposing its own framework or execution model.

---
    

# Why DOM Tasks?

DOM Tasks is designed to feel like a native extension to Playwright rather than another automation framework.

Instead of forcing you to learn a new API, it integrates directly into your existing workflow.

```python
result = await solver.solve(
    RecaptchaChallenge(
        page=page,
    )
)
```

Everything else remains under your control.

- Use your own waits.
- Use your own logging.
- Use your own retry strategy.
- Use your own browser configuration.
- Use your own proxies.
- Continue using Playwright exactly as you already do.

The SDK focuses on solving CAPTCHAs and immediately returns control back to your automation.


# RESPONSIBLE USE
We encourage the responsible and ethical use of automation technologies and does not endorse or encourage the misuse of this software to violate applicable laws, contractual obligations, or the rights of others.


# License

Copyright © 2026 DOM Tasks.

LICENSE GRANT

Subject to this License, you are granted permission to:

    ✓ Install and use this software.

    ✓ Use this software in personal projects and in commercial or internal business applications developed by you or your organization.

    ✓ Modify this software solely for your own internal use.


You may NOT:


    ✗ Redistribute this software, whether modified or unmodified.

    ✗ Publish or make available modified versions of this software to any third party.

    ✗ Sell, sublicense, rent, lease, assign, or otherwise transfer this software or any modified version of it.

    ✗ Remove, alter, or obscure any copyright notices, trademarks, branding, attribution, or license notices contained in the software.

    ✗ Represent modified versions as the original software.

    ✗ Use the software in violation of applicable laws.

    ✗ Use this software or any substantial portion of it to develop, distribute, or commercialize a competing software library, SDK, or similar product.


OWNERSHIP

    No ownership rights are transferred under this License. Ownership of the software and all intellectual property rights remain with the copyright holder.

    All rights not expressly granted under this License are reserved by the copyright holder.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...

# Disclaimer: 

This is an unofficial package and it is not affiliated or endorsed by the maintainers of Playwright, package name indicates compatibility.
