CodeNewbie Community 🌱

Cover image for How to bypass captcha with 2captcha API and Selenium using JavaScript
Ted Ngeene
Ted Ngeene

Posted on • Updated on • Originally published at tngeene.com

How to bypass captcha with 2captcha API and Selenium using JavaScript

Spam is a big nightmare for website owners. With the dawn of bots, this challenge has never been more prominent. Completely Automated Public Turing tests to tell Computers and Humans Apart(or CAPTCHA as they are commonly known) were introduced to tackle this issue.

The squiggly lines and words of the past are less common nowadays and have been replaced by Google's version 2 of CAPTCHA, known as reCAPTCHA. However, bots are becoming more advanced and can bypass almost any captcha. With a little spare time and, a few resources, we can make a program that bypasses the all too annoying CAPTCHA. In this tutorial, we'll make use of the captcha bypass software, 2captcha.

https://res.cloudinary.com/practicaldev/image/fetch/s--TImx3P4Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h2oqd92dh8bo0ute3qvn.jpeg

Why are we doing this?

Okay, I know some of you might be wondering, why would we need to bypass captcha? and most importantly; is this even legal? No, it is not illegal to bypass 2captcha. Whatever we'll be building is within the confines of the law. Secondly, this article is intended for anyone;

  1. Curious about how you can bypass captcha
  2. Building web scrapers that would need to bypass a captcha

*Disclosure: I only recommend products I would use myself and all opinions expressed here are my own. This post may contain affiliate links that at no additional cost to you, I may earn a small commission.

What is 2captcha API and how does it work?

2Captcha.com is a captcha solving service that automates the captcha solving process. They have an API and several packages that wrap around different programming languages. All you need is to register on their website, get an API key and make requests to their API.

Note: They charge a small rate for every captcha solved, however, the fee is quite minimal.

Signup Process and supported languages

https://res.cloudinary.com/practicaldev/image/fetch/s--JgfXuOWJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vdobzdwc4thex7mwocho.png

https://res.cloudinary.com/practicaldev/image/fetch/s--OEXnGqQA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szwihqwt8xxrtpnz64fn.png

Supported captchas the software solves include;

https://res.cloudinary.com/practicaldev/image/fetch/s--px3AuiEX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/11ybxotkegschanhgq9i.png

Requirements and Setup

  • For this tutorial, we'll utilize the 2captcha API. You'll need to have a developer account to use. You can head over to this link and sign up
  • The source code we'll be using can be found here. Setup instructions have been linked in the project README file. Feel free to clone the repository and tinker around.

Let's dive in.

Automating with Selenium

Before we get carried away by CAPTCHA, we need to understand the process our program will follow. I'm going to use selenium and node.js. Selenium is a browser automation service that provides extensions that allow programs to emulate browser interactions. It supports an array of browsers; from chrome, firefox, safari, and so forth, by integrating with their web drivers.

For this tutorial, I'll be using chrome driver since chrome is my default browser. To setup selenium and chromedriver, run

 npm i selenium-webdriver
 npm i chromedriver

Enter fullscreen mode Exit fullscreen mode

This will write to the package.json file initialized in your node application.

Installing 2Captcha Dependencies

Next, we'll need to install 2captcha's node.js package

npm i @infosimples/node_two_captcha

Enter fullscreen mode Exit fullscreen mode

This package will do the heavy lifting in terms of interacting with 2Captcha API.

Finally, we'll install dotenv since we'll be having sensitive keys that we need stored in an environment variables file.

npm i dotenv

Enter fullscreen mode Exit fullscreen mode

Project Code

Open an index.js file at the root of your project directory and paste the following code. We'll go over the code in-depth in the next section.

require("chromedriver");
require("dotenv").config();
const Client = require("@infosimples/node_two_captcha");
const { Builder, By, Key, until } = require("selenium-webdriver");

const client = new Client(process.env.CAPTCHA_API_KEY, {
  timeout: 60000,
  polling: 5000,
  throwErrors: false,
});

const initiateCaptchaRequest = async () => {
  console.log("solving captcha...");
  try {
    client
      .decodeRecaptchaV2({
        googlekey: process.env.GOOGLE_CAPTCHA_KEY,
        pageurl: process.env.WEBSITE_URL,
      })
      .then(function (response) {
        //   if captcha is solved, launch selenium driver.
        launchSelenium(response);
      });
  } finally {
    //   do something
  }
};

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function launchSelenium(response) {
  if (response) {
    console.log("Captcha Solved! Launching Browser instance...");
    let driver = await new Builder().forBrowser("chrome").build();
    // Navigate to Url
    await driver.get(process.env.WEBSITE_URL);

    await driver.findElement(By.id("name")).sendKeys("Ted");
    await driver.findElement(By.id("phone")).sendKeys("000000000");
    await driver.findElement(By.id("email")).sendKeys("tngeene@captcha.com");
    await driver.findElement(By.id("comment-content")).sendKeys("test comment");

    const gCaptchResponseInput = await driver.findElement(
      By.id("g-recaptcha-response")
    );
    await driver.executeScript(
      "arguments[0].setAttribute('style','type: text; visibility:visible;');",
      gCaptchResponseInput
    );

    await gCaptchResponseInput.sendKeys(`${response.text}`);

    await driver.executeScript(
      "arguments[0].setAttribute('style','display:none;');",
      gCaptchResponseInput
    );

    await driver.findElement(By.id("send-message")).click();

    // wait 8 seconds and close browser window
    await sleep(8000);

    driver.quit();
  } else {
    //   if no text return request time out message
    console.log("Request timed out.");
  }
}

(async function main() {
  const response = await initiateCaptchaRequest();
})();

Enter fullscreen mode Exit fullscreen mode

Importing Packages

require("chromedriver");
require("dotenv").config();
const Client = require("@infosimples/node_two_captcha");
const { Builder, By, Key, until } = require("selenium-webdriver");

Enter fullscreen mode Exit fullscreen mode

These lines are essentially referencing the packages we'll be using. We're telling the program that we'll require to use chrome driver, dotenv, the node_two_captcha, and selenium packages.

Interacting with imported packages

const client = new Client(process.env.CAPTCHA_API_KEY, {
  timeout: 60000,
  polling: 5000,
  throwErrors: false,
});

Enter fullscreen mode Exit fullscreen mode

The first package we need to use is the node_two_captcha package. The first parameter of the TwoCaptchaClient constructor is your API key from 2Captcha. In our case above, we referenced an environment variable (CAPTCHA_API_KEY). More on this below. The other parameters are:

  • timeout: Time (milliseconds) to wait before giving up on waiting for a captcha solution.
  • polling: Time (milliseconds) between polls to 2captcha server. 2Captcha documentation suggests this time to be at least 5 seconds, or you might get blocked.
  • throwErrors : Whether the client should throw errors or just log the errors.

Environment variable.

An environment variable is a dynamic-named value that can affect the way running processes will behave on a computer. They are part of the environment in which a process runs. For example, a running process can query the value of the TEMP environment variable to discover a suitable location to store temporary files, or the HOME or USERPROFILE variable to find the directory structure owned by the user running the process.

It's advisable to use environment variables to store sensitive information that we wouldn't want getting into unauthorized hands, for example, our 2Captcha API key. Create a env file at the root of your project folder. Modify it to this.

 CAPTCHA_API_KEY=<api_key_from_2_captcha.com>
 WEBSITE_URL=<website_we'll_be_accessing_captcha>
 GOOGLE_CAPTCHA_KEY=<google_captcha_site_key>

Enter fullscreen mode Exit fullscreen mode

Paste the api key value from 2captcha dashboard on the CAPTCHA_API_KEY field.

Captcha Solving Pseudocode

Now that we have our account setup, we'll do the actual capture bypassing, which brings us to the next part.

For this tutorial, i'll be bypassing the capture on this sample form

https://res.cloudinary.com/practicaldev/image/fetch/s--F4Bz13C_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qkgdk3qldwr178k6rtb0.png

In order to achieve our objective, we'll need our program to follow these steps.

  1. Launch a browser tab
  2. Fill in the required fields in the form
  3. Solve the captcha
  4. Send the contact message with the solved captcha.

All this will be achieved automatically!! How cool is that?

Retrieving Dom elements

As you can tell from the form, we will need selenium to access the DOM form elements as it automatically fills the inputs. These are; the name, email, phone, comment, and finally there's a hidden google captcha field that takes the solved captcha as an input.

For the visible form fields, all we need to do is open up the dev tools and retrieve the individual ids of the form fields.

This section does just that.

   let driver = await new
    Builder().forBrowser("chrome").build();
    await driver.get(process.env.WEBSITE_URL);

    await driver.findElement(By.id("name")).sendKeys("Ted");
    await driver.findElement(By.id("phone")).sendKeys("000000000");
    await driver.findElement(By.id("email")).sendKeys("tngeene@captcha.com");
    await driver.findElement(By.id("comment-content")).sendKeys("test comment");

Enter fullscreen mode Exit fullscreen mode

What we're telling selenium is, to launch chrome browser, and visit the specified url. Once it does so, find the DOM elements that matches the provided ids. Since these are form inputs, auto-populate those field with the data inside the sendKeys function.

All 2captchas have a hidden text-area that autofills with the solved captcha code once you click the i'm not a robot check. Usually, this has the id set as g-recaptcha-response

https://res.cloudinary.com/practicaldev/image/fetch/s--DRV3vb-q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6v3jdf99wtv974jfhffy.png

Since selenium simulates browser human inputs, it'll be required to make the field visible. We achieve this with this code snippet

  const gCaptchResponseInput = await driver.findElement(
      By.id("g-recaptcha-response")
    );
    await driver.executeScript(
      "arguments[0].setAttribute('style','type: text; visibility:visible;');",
      gCaptchResponseInput
    );

  await gCaptchResponseInput.sendKeys(`${response.text}`);

  await driver.executeScript(
      "arguments[0].setAttribute('style','display:none;');",
      gCaptchResponseInput
    );
 await driver.findElement(By.id("send-message")).click();

Enter fullscreen mode Exit fullscreen mode

This section typically makes the field visible, auto-populates the field with the solved captcha, hides the field again, and finally, the button click is simulated to send the comment with the solved captcha.

Finally, we'll close the browser tab 8 seconds after the captcha has been solved.

// wait 8 seconds and close browser window
    await sleep(8000);

    driver.quit();

Enter fullscreen mode Exit fullscreen mode

All the fore-mentioned functionality resides in the launchSelenium() function. We need to tie it all together with the 2captcha service.

From the index.js file, you can see we have a initiateCaptchaRequest() function.

const initiateCaptchaRequest = async () => {
  console.log("solving captcha...");
  try {
    client
      .decodeRecaptchaV2({
        googlekey: process.env.GOOGLE_CAPTCHA_KEY,
        pageurl: process.env.WEBSITE_URL,
      })
      .then(function (response) {
        //   if captcha is solved, launch selenium driver.
        launchSelenium(response);
      });
  } finally {
    //   do something
  }
};

Enter fullscreen mode Exit fullscreen mode

We are calling the node_two_captcha client we'd initialized before.

The WEBSITE_URL is the webpage of our captcha form. Fill it in the .env file.

GOOGLE_CAPTCHA_KEY is a special identifier found in all web forms having captcha, we can retrieve it by also opening dev tools, and searching the data-sitekey keyword.

https://res.cloudinary.com/practicaldev/image/fetch/s--EWcZ2FeR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lp1rxds2suvwbtgrktdn.png

Retrieve the value and paste it in the .env, GOOGLE_CAPTCHA_KEY value. node_two_captcha sends this key under the hood to 2capthca API, which then returns an API response of the solved captcha.

Selenium will only be launched upon a successful captcha solve, which usually takes a few seconds. For Recaptcha version 2, the ETA is usually anytime from 15 seconds to 45seconds. Recaptcha version 3 takes a shorter time.If a request timed out, we log the api response.

Demo

Okay, now your application is set up! It may feel like a lot πŸ˜… but we did a lot of installation. We will now test our application.

To do this, run

npm index.js

Enter fullscreen mode Exit fullscreen mode

https://res.cloudinary.com/practicaldev/image/fetch/s--wo6M1CbL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l2rzq2jqq3zbyu8z86pd.gif

Conclusion

It’s always a dilemma, should websites have a better experience and have simple to bypass the CAPTCHA or should websites aggressively protect themselves from bots and have a bad user experience. The war between websites and bots is never over. Whatever verification method websites pull out, it’s just a matter of time when someone figures out how to bypass it. ~ Filip Vitas

In this guide, we were introduced to 2captcha API, selenium, and a few concepts in 2captcha. By the end of it, I hope you can apply the knowledge gained to build your own captcha bypass service. I mean, if bots can do it, then so should we! A few next steps would be to add a User interface to input our values. You can also look into using the 2captcha API using your preferred programming language and other tools such as puppeteer

Finally, if you liked the content and would like to use 2captcha, sign up with this link.

If you have any questions, you can always leave a comment below, or reach out on these channels;

  1. personal website
  2. Twitter

Source code of demo project can be accessed here.

Use 2captcha responsibly.

Top comments (0)