Skip to main content
Version: v2

Solving Captchas

info

Looking for full developer docs? See them here. This feature is only available on the Scale plan and Enterprise plans.

Some sites won't allow you to bypass their captchas or strictly enforce them to be solved on some sites. You can solve these captchas with Browserless without much effort. You can have a listener waiting to see if a captcha is found and you can also solve them programmatically.

Every captcha you solve costs 10 units from your plan.

note

Many passive captchas can be prevented from showing with our /unblock API, that hides signs of browser automation.

Find a captcha programmatically

You can listen for captchas on the site, in puppeteer it would be like this:

const cdp = await page.createCDPSession();
await new Promise((resolve) =>
cdp.on("Browserless.captchaFound", () => {
console.log("Found a captcha!");
return resolve();
}),
);

Solve a captcha programmatically

You can solve the captcha from code, in puppeteer it would be like this:

const cdp = await page.createCDPSession();
const { solved, error } = await cdp.send("Browserless.solveCaptcha");
console.log({
solved,
error,
});

Script Examples

Puppeteer

Here's a sample snippet you can run to demonstrate this works.

import puppeteer from "puppeteer-core";

const waitForCaptcha = (cdpSession) => {
return new Promise((resolve) => cdpSession.on("Browserless.captchaFound", resolve));
};

const browserWSEndpoint =
"wss://production-sfo.browserless.io/chromium?token=GOES-HERE&timeout=300000";

try {
const browser = await puppeteer.connect({ browserWSEndpoint });

const page = await browser.newPage();
const cdp = await page.createCDPSession();

await page.goto("https://www.google.com/recaptcha/api2/demo", {
waitUntil: "networkidle0",
});

await waitForCaptcha(cdp);
console.log("Captcha found!");

const { solved, error } = await cdp.send("Browserless.solveCaptcha");
console.log({ solved, error });

// Continue...
await page.click("#recaptcha-demo-submit");
await browser.close();
} catch (e) {
console.error("There was a big error :(", e);
process.exit(1);
}

Playwright

Playwright works a bit different than Puppeteer in regards to its pages, as it uses it own browser protocols to communicate. For that reason, you'll need to connect over CDP. And while most of the steps are the same as in Puppeteer, you should use the default existing context and page instead of creating a new one.

import playwright from "playwright-core";

const waitForCaptcha = (cdpSession) => {
return new Promise((resolve) => cdpSession.on("Browserless.captchaFound", resolve));
};
const pwEndpoint = `wss://production-sfo.browserless.io/chromium?token=GOES-HERE`;

try {
const browser = await playwright.chromium.connectOverCDP(pwEndpoint);
// 👇 Queue we're re-using the existing context and page
const context = browser.contexts()[0];
const page = context.pages()[0];

await page.goto("https://www.google.com/recaptcha/api2/demo", {
waitUntil: "networkidle0",
});

const cdp = await page.context().newCDPSession(page);
await waitForCaptcha(cdp);
console.log("Captcha found!");

const { solved, error } = await cdp.send("Browserless.solveCaptcha");

console.log({ solved, error });

// Continue...
await page.click("#recaptcha-demo-submit");
await browser.close();
} catch (e) {
console.error("There was a big error :(", e);
process.exit(1);
}