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
- The page displays a distorted image with text.
- The user types the text into an input field.
- The server validates the input against the expected text.
- 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.

English
Spanish
Russian
Chinese
French
Hindi
Arabic
Bengali
Indonesian
Portuguese
com, 