How to bypass captcha with Playwright
Learn how to bypass captchass using Playwright and the captcha sovler API — code examples and practical tips.
The problem with captchas in bypass Playwright
Captchas exist to stop bots — and they’re good at it. Whether it’s a signup form, a login page, or a simple contact submission, captchas are the first line of defense against automated access. But if your job is testing or scraping, they’re not just a challenge — they’re a blocker.
In this guide, you’ll learn how to detect captchas on the page, submit them to 2Captcha, wait for a valid token, and inject the solution — all through Playwright.
Playwright capabilities
API for all browsers and platforms:
- Cross-browser: Playwright works with Chromium, WebKit, and Firefox — no need to change your code to switch engines.
- Cross-platform: Write once, run anywhere — Linux, macOS, Windows. Headless or full browser mode. Local or CI.
- Cross-language: Use it with TypeScript, JavaScript, Python, .NET, or Java — whatever fits your stack.
- Mobile web testing: Emulate Chrome for Android and Safari on iOS using the same engine and APIs. Works identically on desktop and cloud environments.
Use cases
- Scraping JavaScript-heavy sites: Capture dynamic content that only appears after the page loads and renders in the browser.
- Handling complex user flows: Automate multi-step forms, login sequences, or any page behind interaction barriers.
- Extracting from single-page apps: Navigate and pull data from Vue, React, or Angular apps without relying on static HTML.
- Test automation with real browsers: Combine scraping and testing — collect data while validating that the page works as expected.
- Run headless in production: Automate everything without opening a GUI — perfect for servers and pipelines.
Install dependencies
To get started, you’ll need a Node.js environment with Playwright installed, a way to make HTTP requests, and access to your {{site_name}} API key.
Step 1: Initialize your project
mkdir captcha-playwright && cd captcha-playwright
npm init -y
Step 2: Install required packages
npm install playwright node-fetch dotenv
Step 3: Create .env and store your API key
API_KEY=your_2captcha_api_key_here
require('dotenv').config();
const API_KEY = process.env.API_KEY;
Detect the captcha type
Before you can solve a captcha, you need to know what you’re dealing with.
Step 1: Inspect the page
<div class="g-recaptcha" data-sitekey="...">
src="https://www.google.com/recaptcha/api.js"
Step 2: Extract the sitekey
To solve a CAPTCHA, you need the sitekey
used by the CAPTCHA provider. This is a public identifier embedded in the HTML of the target page. You can find it using browser devtools.
Look for an element like this:
<div class="g-recaptcha" data-sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"></div>
Or for invisible CAPTCHAs:
<script src="https://www.google.com/recaptcha/api.js?render=SITE_KEY"></script>
Copy the value of the data-sitekey
or the render
parameter. You'll need it when submitting the CAPTCHA-solving request.
Step 3: Note the URL
You also need the full URL of the page where the CAPTCHA is displayed. This is required by most CAPTCHA-solving APIs to simulate a realistic browser environment.
In Playwright, you can get it programmatically:
const url = page.url();
Or simply copy it from the browser’s address bar. Combine it with the sitekey in your API request to solve the captcha correctly.
Chrome extension
Install the captcha solver extension for Chrome.
Submit
Step 1: Send the task
API v1
const res = await fetch('https://2captcha.com/in.php', {
method: 'POST',
body: new URLSearchParams({
key: API_KEY,
method: 'userrecaptcha',
googlekey: SITE_KEY,
pageurl: SITE_URL,
json: '1',
}),
});
API v2
const res = await fetch('https://api.2captcha.com/createTask', {
method: 'POST',
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: "RecaptchaV2TaskProxyless",
websiteURL: SITE_URL,
websiteKey: SITE_KEY,
isInvisible: false
}
}),
});
Step 2: Wait for the token
After submitting the task, the API needs some time to solve the CAPTCHA. You must poll the API periodically until the solution is ready.
API v1
const waitForToken = async (captchaId) => {
const url = `https://2captcha.com/res.php?key=${API_KEY}&action=get&id=${captchaId}&json=1`;
for (let i = 0; i < 20; i++) {
const res = await fetch(url);
const data = await res.json();
if (data.status === 1) return data.request; // solution is ready
if (data.request !== 'CAPCHA_NOT_READY') throw new Error(`Unexpected error: ${data.request}`);
await new Promise(resolve => setTimeout(resolve, 5000)); // wait 5 seconds
}
throw new Error('Timeout: CAPTCHA solution not received within expected time');
};
API v2
const waitForToken = async (taskId) => {
const url = 'https://api.2captcha.com/getTaskResult';
const body = {
clientKey: API_KEY,
taskId,
};
for (let i = 0; i < 20; i++) {
await new Promise(resolve => setTimeout(resolve, 5000));
const res = await fetch(url, {
method: 'POST',
body: JSON.stringify(body),
});
const json = await res.json();
if (json.status === 'ready') return json.solution.gRecaptchaResponse;
if (json.status === 'failed') throw new Error(`Captcha failed: ${JSON.stringify(json)}`);
}
throw new Error('Timeout: CAPTCHA solution not ready after multiple attempts');
};
This logic ensures the program waits for a valid CAPTCHA solution before proceeding. It's essential to include this in any implementation involving CAPTCHA solving, especially in real-world scenarios where delays are common.
Step 3: Poll for the result
API v1
const res = await fetch(`https://2captcha.com/res.php?key=${API_KEY}&action=get&id=${captchaId}&json=1`);
API v2
const res = await fetch('https://api.2captcha.com/getTaskResult', {
method: 'POST',
body: JSON.stringify({
clientKey: API_KEY,
taskId
}),
});
Inject the response
await page.evaluate((token) => {
document.querySelector('[name="g-recaptcha-response"]').value = token;
}, token);
Full working example
The final example includes launching Playwright, solving a captcha, and submitting a form.
Debugging tips
- Check
sitekey
andpageurl
- Retry if
CAPCHA_NOT_READY
- Use real user-agent and add wait times
Final words
Playwright + {{site_name}} allows you to automate and bypass most captcha challenges reliably.