homeresume
 
   

Automated captcha solver

Published January 22, 2023Last updated October 23, 20243 min read

Many websites use CAPTCHAs to prevent bots from submitting forms and accessing their services. CAPTCHA is designed to separate humans from bots when accessing a website or service.

CAPTCHA can be text-based, where the user types numbers and letters displayed on the given image. Also, some other CAPTCHAs, like reCAPTCHA and hCAPTCHA include "I'm not a robot" checkbox, selecting specific photos, and identifying objects inside an image.

On the other side, there are solutions in the form of captcha solving software. This post will cover how to bypass captcha with 2captcha service using Puppeteer and Node.js.

2captcha can solve different types of CAPTCHAs, from text-based to reCAPTCHAs and hCAPTCHAs. It provides an API that receives CAPTCHA parameters and returns a decoded result.

Prerequisites

  • API key
  • some amount of deposited funds in the account

Browser automation

The following example solves reCAPTCHA inside the browser using the Puppeteer plugin. A headless option is disabled to show visual feedback, reCAPTCHA is colored in violet when it's detected and green when it's solved. The screenshot for the solved CAPTCHA is stored as an image.

require('dotenv/config');
const { executablePath } = require('puppeteer');
const puppeteer = require('puppeteer-extra');
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha');
puppeteer.use(
RecaptchaPlugin({
provider: {
id: '2captcha',
token: process.env.CAPTCHA_SOLVER_API_KEY
},
visualFeedback: true
})
);
puppeteer
.launch({ headless: false, executablePath: executablePath() })
.then(async (browser) => {
const page = await browser.newPage();
await page.goto(
'https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php'
);
await page.solveRecaptchas();
await page.click(`button[type=submit]`);
await page.screenshot({ path: 'response.png', fullPage: true });
await browser.close();
})
.catch(console.error);

API call and browser automation

The examples below utilize 2captcha API and solve a different type of CAPTCHAs for the given site key and page URL. After that, it submits the form with the solved CAPTCHA. The site key is inside the CAPTCHA iFrame element URL in src attribute, and it's usually k or siteKey query parameter.

  • reCAPTCHA
require('dotenv/config');
const Captcha = require('2captcha');
const puppeteer = require('puppeteer');
const solver = new Captcha.Solver(process.env.CAPTCHA_SOLVER_API_KEY);
const pageUrl = 'https://www.google.com/recaptcha/api2/demo';
(async () => {
try {
const browser = await puppeteer.launch({
headless: false,
executablePath: puppeteer.executablePath()
});
const page = await browser.newPage();
await page.goto(pageUrl, { waitUntil: 'load' });
const iFrameSrc = await page.$eval('iframe', (iframe) => iframe.src);
const queryParams = new URLSearchParams(iFrameSrc);
const siteKey = queryParams.get('sitekey') || queryParams.get('k');
const response = await solver.recaptcha(siteKey, pageUrl);
await page.$eval(
'#g-recaptcha-response',
(element, value) => (element.value = value),
response.data
);
await page.click('input[type="submit"]');
await page.screenshot({ path: 'recaptcha-response.png', fullPage: true });
await browser.close();
} catch (error) {
console.error(error);
}
})();
  • hCAPTCHA
require('dotenv/config');
const Captcha = require('2captcha');
const puppeteer = require('puppeteer');
const solver = new Captcha.Solver(process.env.CAPTCHA_SOLVER_API_KEY);
const pageUrl = 'https://accounts.hcaptcha.com/demo';
(async () => {
try {
const browser = await puppeteer.launch({
headless: false,
executablePath: puppeteer.executablePath()
});
const page = await browser.newPage();
await page.goto(pageUrl, { waitUntil: 'load' });
const iFrameSrc = await page.$eval('iframe', (iframe) => iframe.src);
const queryParams = new URLSearchParams(iFrameSrc);
const siteKey = queryParams.get('sitekey') || queryParams.get('k');
const response = await solver.hcaptcha(siteKey, pageUrl);
await page.$eval(
'textarea[name="h-captcha-response"]',
(element, value) => (element.value = value),
response.data
);
await page.click('#hcaptcha-demo-submit');
await page.screenshot({ path: 'hcaptcha-response.png', fullPage: true });
await browser.close();
} catch (error) {
console.error(error);
}
})();

Disclaimer

Please check the website's terms of service before using captcha solver. Some websites may have terms of service that prohibit such software use.

Boilerplate

Here is the link to the boilerplate I use for the development.