Solving Image CAPTCHAs with Playwright

Solving Image CAPTCHAs with Playwright

Posted on 2026-09-18 | 2 min read | Category: Playwright | By DeathByCaptcha Engineering Team

Playwright


Image CAPTCHAs are the oldest type: distorted text images that humans read and bots struggle with. They appear on login forms, registration pages, and comment sections. DeathByCaptcha solves image CAPTCHAs with OCR technology.

How Image CAPTCHAs Work

  1. The page displays a distorted image with text.
  2. The user types the text into an input field.
  3. The server validates the input against the expected text.
  4. If correct, the form submits. If not, a new image appears.

Detecting Image CAPTCHAs in Playwright

# Common selectors for image CAPTCHAs
captcha_img = page.query_selector("img[src*=captcha]")
if not captcha_img:
    captcha_img = page.query_selector("img[alt*=captcha]")

if captcha_img:
    print("Image CAPTCHA detected")
    captcha_url = captcha_img.get_attribute("src")

Solving with DeathByCaptcha

Image CAPTCHAs use type=0:

import base64
from playwright.sync_api import sync_playwright
import deathbycaptcha

client = deathbycaptcha.SocketClient(username, password)

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com/login")

    captcha_img = page.query_selector("img[src*=captcha]")
    captcha_src = captcha_img.get_attribute("src")

    import requests
    response = requests.get(captcha_src)
    captcha_bytes = response.content

    result = client.decode(type=0, raw=captcha_bytes)
    print("Solution:", result["text"])

    page.fill("input[name=captcha]", result["text"])
    page.click("button[type=submit]")

    browser.close()

Using Base64 Encoding

Some CAPTCHAs are embedded as base64 images:

# Handle base64 CAPTCHA images
captcha_src = captcha_img.get_attribute("src")
if captcha_src.startswith("data:image"):
    base64_data = captcha_src.split(",")[1]
    captcha_bytes = base64.b64decode(base64_data)
else:
    response = requests.get(captcha_src)
    captcha_bytes = response.content

Combined with Browser Automation

The full flow for login with image CAPTCHA:

import requests
from playwright.sync_api import sync_playwright
import deathbycaptcha

client = deathbycaptcha.SocketClient(username, password)

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto("https://example.com/login")

    page.fill("input[name=username]", "my_username")
    page.fill("input[name=password]", "my_password")

    captcha_img = page.query_selector("img[src*=captcha]")
    if captcha_img:
        captcha_src = captcha_img.get_attribute("src")
        response = requests.get(captcha_src)
        result = client.decode(type=0, raw=response.content)
        page.fill("input[name=captcha]", result["text"])

    page.click("button[type=submit]")
    page.wait_for_url("**/dashboard**")
    print("Login successful")

    browser.close()

Key Differences from reCAPTCHA

  • Type parameter: Use type=0 for image CAPTCHAs, type=4 for reCAPTCHA v2.
  • Raw data: Pass the image bytes directly, not a sitekey.
  • No sitekey: Image CAPTCHAs don't use sitekeys. They use the image data.
  • Input field: You need to find the correct input field for the CAPTCHA text.

Troubleshooting

  • Wrong input field: Inspect the page to find the correct CAPTCHA input name.
  • Image not loading: Some CAPTCHAs require cookies from the current session.
  • Rate limiting: Image CAPTCHAs may be rate-limited. Add delays between attempts.
  • Multiple CAPTCHAs: Some pages have multiple CAPTCHA images. Solve all of them.

For API documentation, see the API reference and client libraries.

Common pitfalls

  • Using a CAPTCHA solving service for illegitimate purposes instead of legitimate automation and testing.
  • Hard-coding credentials or API keys in client-side code that users can inspect.
  • Sending the wrong CAPTCHA type parameter, which returns incorrect or empty responses.
  • Failing to poll for the solution status and not handling timeouts gracefully.
  • Scaling automation without monitoring error rates, response times, and CAPTCHA type coverage.
DBC
Written by DeathByCaptcha Engineering Team
DeathByCaptcha engineers build and operate the CAPTCHA solving technology behind this site. Articles are written by our technical team and checked for accuracy before publishing.
Reviewed by DeathByCaptcha Editorial Team

Get your API key — start solving

Free to try · No credit card · Python, Node.js, Java, C# SDKs

Get your API key


Status: OK

Servers are fully operational with faster than average response time.
  • Average solving time
  • 3 seconds - Normal CAPTCHAs (1 min. ago)
  • 16 seconds - reCAPTCHA V2, V3 (1 min. ago)
  • 7 seconds - others (1 min. ago)
Chrome and Firefox logos
Browser extensions available

Updates

  1. May 13: Crypto payments got better! You can now purchase your CAPTCHAs using cryptocurrency through the Hekelet payment processor at https://deathbycaptcha.com/user-pay and receive an extra 20% FREE CAPTCHA credit with every package purchased this way.
  2. Apr 15: GitHub Updates: We’ve upgraded our libraries, expanded sample code, enhanced documentation, and added support for C++ and Go, making integration smoother than ever. Explore what’s new at github.com/deathbycaptcha!
  3. Jan 27: RESOLVED - If your email to one of our official addresses ([email protected], [email protected], or [email protected]) has bounced or you haven’t received a response, please try resending it or reach out via our Live Chat Support at https://deathbycaptcha.com/es/contact.

  4. Previous updates…

Support

Our system is designed to be completely user-friendly and easy-to-use. Should you have any trouble with it, simply email us at DBC technical support emailcom, and a support agent will get back to you as soon as possible.

Live Support

Available Monday to Friday (10am to 4pm EST) Live support image. Link to live support page