CAPTCHAFORUM
Administrator
https://2captcha.com/h/captcha-bypass-playwright
CAPTCHAs are designed to block bots — and they do it well. But if you're building automation tools, doing QA, or scraping dynamic sites, CAPTCHAs become an obstacle. In this guide, we’ll walk through how to use Playwright with the 2Captcha API to bypass CAPTCHAs effectively.
Why CAPTCHAs Matter in Automation
Whether you're automating logins, signups, or extracting data from JavaScript-heavy websites, CAPTCHAs will appear. Bypassing them is critical to keep your scripts running smoothly — and legally.
What You’ll Learn
- How to detect and identify reCAPTCHA and hCaptcha on a page
- How to submit a CAPTCHA challenge to 2Captcha
- How to retrieve and inject the solution in Playwright
- How to avoid common pitfalls
Getting Started
Step 1: Set up your Node project
Code:
mkdir captcha-playwright && cd captcha-playwright
npm init -y
npm install playwright node-fetch dotenv
npx playwright install
Create a .env file in the root:
Code:
API_KEY=your_2captcha_api_key_here
In your script:
Code:
require('dotenv').config();
const API_KEY = process.env.API_KEY;
Detecting CAPTCHA Type
Inspect the page for common CAPTCHA types:
reCAPTCHA:
Code:
<div class="g-recaptcha" data-sitekey="...">
<script src="https://www.google.com/recaptcha/api.js"></script>
hCaptcha:
Code:
<div class="h-captcha" data-sitekey="...">
<script src="https://hcaptcha.com/1/api.js"></script>
Grab the data-sitekey and the page URL. You’ll need both for 2Captcha.
Submitting CAPTCHA to 2Captcha
Using API v1 (reCAPTCHA example)
Code:
const fetch = require('node-fetch');
const submitCaptcha = async () => {
const params = new URLSearchParams();
params.append('key', API_KEY);
params.append('method', 'userrecaptcha');
params.append('googlekey', 'SITE_KEY_HERE');
params.append('pageurl', 'https://target-website.com');
params.append('json', 1);
const res = await fetch('https://2captcha.com/in.php', { method: 'POST', body: params });
const data = await res.json();
if (data.status !== 1) throw new Error('Submission failed');
return data.request; // captchaId
};
Poll for Result
Code:
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;
if (data.request !== 'CAPCHA_NOT_READY') throw new Error(`2Captcha Error: ${data.request}`);
await new Promise(r => setTimeout(r, 5000));
}
throw new Error('Timed out waiting for captcha');
};
Injecting CAPTCHA Token in Playwright
Once you get the token:
Code:
await page.evaluate(token => {
document.querySelector('[name="g-recaptcha-response"]').value = token;
}, token);
// Optional: Submit the form
await page.click('#submit-button');
// Or if JS handles it:
await page.evaluate(() => document.querySelector('form').submit());
Full Example
Code:
const { chromium } = require('playwright');
require('dotenv').config();
const fetch = require('node-fetch');
const API_KEY = process.env.API_KEY;
const SITE_URL = 'https://www.google.com/recaptcha/api2/demo';
const SITE_KEY = '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI';
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
await page.goto(SITE_URL);
// Submit to 2Captcha
const captchaId = await submitCaptcha();
// Wait for solution
const token = await waitForToken(captchaId);
// Inject and submit
await page.evaluate(token => {
document.querySelector('[name="g-recaptcha-response"]').value = token;
}, token);
await page.click('#recaptcha-demo-submit');
await page.waitForSelector('.recaptcha-success');
console.log('Captcha solved!');
await browser.close();
})();