Solving CAPTCHAs with Playwright and DeathByCaptcha: Complete Guide

Solving CAPTCHAs with Playwright and DeathByCaptcha: Complete Guide

Posted on 2026-09-17 | 3 min read | Category: Playwright | By DeathByCaptcha Engineering Team

Playwright


Playwright gives you full control over a real browser. When a CAPTCHA blocks your flow, you need a way to solve it without losing page state. This guide shows you how to integrate DeathByCaptcha into Playwright scripts for Python, Node.js, C#, and Java.

How It Works

The pattern is the same across all languages:

  1. Launch Playwright and navigate to the target page.
  2. Extract the site key from the DOM or network requests.
  3. Send the CAPTCHA to the DeathByCaptcha API for solving.
  4. Inject the token back into the page using JavaScript evaluation.
  5. Submit the form and continue your automation flow.

Python Example

pip install deathbycaptcha-official playwright
playwright install
import json
from playwright.sync_api import sync_playwright
import deathbycaptcha

username = "your_username"
password = "your_password"
page_url = "https://www.google.com/recaptcha/api2/demo"

client = deathbycaptcha.SocketClient(username, password)
print("Balance:", client.get_balance())

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    page = browser.new_page()
    page.goto(page_url, timeout=60000)
    googlekey = page.get_attribute("#recaptcha-demo", "data-sitekey")

    result = client.decode(type=4, token_params=json.dumps({"googlekey": googlekey, "pageurl": page_url}))
    print("Solution:", result["text"])

    page.evaluate("document.getElementById('g-recaptcha-response').value='%s'" % result["text"])
    page.click("#recaptcha-demo-submit")
    print(page.text_content(".recaptcha-success"))

    browser.close()

Node.js Example

npm install deathbycaptcha-lib playwright
npx playwright install
const { chromium } = require("playwright");
const { SocketClient } = require("deathbycaptcha-lib");

const username = "your_username";
const password = "your_password";
const pageUrl = "https://www.google.com/recaptcha/api2/demo";

(async () => {
  const client = new SocketClient(username, password);
  const browser = await chromium.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto(pageUrl, { timeout: 60000 });
  const googleKey = await page.getAttribute("#recaptcha-demo", "data-sitekey");

  const solution = await new Promise((resolve) => {
    client.decode({ extra: { type: 4, token_params: JSON.stringify({ googlekey: googleKey, pageurl: pageUrl }) } }, resolve);
  });

  console.log("Solution:", solution.text);

  await page.evaluate((token) => {
    document.getElementById("g-recaptcha-response").value = token;
  }, solution.text);
  await page.click("#recaptcha-demo-submit");
  await page.waitForSelector(".recaptcha-success");
  console.log("Success");

  await browser.close();
})();

C# Example

dotnet add package DeathByCaptcha
dotnet add package Microsoft.Playwright
using System;
using System.Collections;
using System.Text.Json;
using DeathByCaptcha;
using Microsoft.Playwright;

string username = "DBC_USERNAME";
string password = "DBC_PASSWORD";
string pageUrl = "https://www.google.com/recaptcha/api2/demo";

using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync();
var page = await browser.NewContextAsync().Then(ctx => ctx.NewPageAsync());
await page.GotoAsync(pageUrl, new PageGotoOptions { Timeout = 60000 });
string? googleKey = await page.GetAttributeAsync("#recaptcha-demo", "data-sitekey");

var captchaData = new Hashtable { ["type"] = 4, ["token_params"] = JsonSerializer.Serialize(new { googleKey, pageUrl }) };
DeathByCaptcha.Client client = new DeathByCaptcha.HttpClient(username, password);
Captcha? solution = client.Decode(Client.DefaultTokenTimeout, captchaData);

Console.WriteLine("Solution: {0}", solution!.Text);

await page.EvaluateAsync(
    "value => document.getElementById('g-recaptcha-response').value = value;",
    solution.Text);
await page.ClickAsync("#recaptcha-demo-submit");
await page.WaitForSelectorAsync(".recaptcha-success");
Console.WriteLine("Success");

await browser.CloseAsync();

Java Example

<!-- Add dependencies to pom.xml: -->
<!-- io.github.deathbycaptcha:deathbycaptcha-java-library:4.7.0 -->
<!-- com.microsoft.playwright:playwright:1.52.0 -->
import com.DeathByCaptcha.*;
import com.microsoft.playwright.*;
import org.json.JSONObject;

String username = "DBC_USERNAME";
String password = "DBC_PASSWORD";
String pageUrl = "https://www.google.com/recaptcha/api2/demo";

Playwright playwright = Playwright.create();
Browser browser = playwright.chromium().launch();
Page page = browser.newContext().newPage();
page.navigate(pageUrl);
String siteKey = page.getAttribute("#recaptcha-demo", "data-sitekey");

Client client = new HttpClient(username, password);
JSONObject params = new JSONObject();
params.put("googlekey", siteKey);
params.put("pageurl", pageUrl);
Captcha captcha = client.decode(params);

System.out.println("Solution: " + captcha.text);

page.evaluate(
    "value => document.getElementById('g-recaptcha-response').value = value",
    captcha.text);
page.click("#recaptcha-demo-submit");
page.waitForSelector(".recaptcha-success");
System.out.println("Success");

browser.close();
playwright.close();

Key Configuration

  • type=4 for reCAPTCHA v2 (visible checkbox). Use type=2 for invisible reCAPTCHA.
  • SocketClient is faster than HttpClient for Python and Node.js. C# and Java default to HttpClient.
  • headless=True works for most sites. Switch to headless=False if the CAPTCHA provider detects headless browsers.

For complete API documentation, see the API reference and the client libraries on GitHub.

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
  • 2 seconds - Normal CAPTCHAs (1 min. ago)
  • 15 seconds - reCAPTCHA V2, V3 (1 min. ago)
  • 12 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