[GUIDE] Solving Google reCaptcha V2 in puppeteer

debster

Newbie
Joined
Mar 27, 2023
Messages
28
Reaction score
9
Hey!, I wrote a simple JS function to solve captchas using services like 2captcha, death by captcha etc
If you're using vanilla puppeteer there is already a library for this, this code if for people using puppeteer librarys without wrappers for captcha

Code:
async function solveCaptcha(page, in_url, res_url,sleepFunc) {
    const currentUrl = await page.url();
    const dataSVal = await page.evaluate('document.querySelector("#recaptcha").getAttribute("data-s")')
    const datasite_key = await page.evaluate('document.querySelector("#recaptcha").getAttribute("data-sitekey")')
  
    const PARAMS_ID = {
      key: 'API-KEY',
      method: "userrecaptcha", //this method will differ from service to service, "userrecaptcha is for 2captcha"
      googlekey: datasite_key,
      pageurl: currentUrl,
      "data-s": dataSVal,
    };
    //To solve the captcha you have to submit HTTP POST request to the service API URL, for 2captcha its http://2captcha.com/in.php
    const getIdRequest = await axios.get(in_url, { params: PARAMS_ID });
    const getIdData = getIdRequest.data;
    // removing the OK prefix so the ID can be used
    const getId = getIdData.substring(3);
 
    if (getId.length > 50) {
      throw new Error("Captcha ID length is invalid.");
    }
 
    console.log(`CAPTCHA ID = ${getIdData}`);
 
    // getting a valid response takes atleast 20 seconds
    await sleepFunc(20);
 
    const PARAMS_TOKEN = {
      key: 'a3b9bed8dc883d8834ad2059bccce82c',
      action: "get",
      id: getId,
    };
 
    // sends a request to 2captcha every 5 seconds to check if the captcha is ready
    do {
      await timeSleep(5)
      const getTokenRequest = await axios.get(res_url, { params: PARAMS_TOKEN });
      var getTokenData = getTokenRequest.data;
      var token = getTokenData.substring(3);
      console.log("Captcha not ready....");
    } while (token === "CHA_NOT_READY");
 
    if (token.length > 1000 || token.length < 30) {
      throw new Error("Invalid captcha token length.");
    }
 
    console.log("Token found....");
    console.log(`CAPTCHA TOKEN = ${token}`);
  

    // Injects token into html and initates the callback
    try {
      await page.evaluate((t) => {
        document.getElementById("g-recaptcha-response").innerHTML = t;
      }, token);
    } catch (error) {
      throw new Error("Failed to inject token. because of error = " + error);
    }
    const finalToken = await replaceAsync(token,/-/g,() => '')
    await page.evaluate((t) => {
      submitCallback(t);
      },finalToken);
  
  }


the replaceAsync function removes all "-" from the final token here it is
Code:
async function replaceAsync(string, regexp, replacerFunction) {
  const replacements = await Promise.all(
      Array.from(string.matchAll(regexp),
          match => replacerFunction(...match)));
  let i = 0;
  return string.replace(regexp, () => replacements[i++]);
}

the sleepFunc is just to make life easier
Code:
function timeSleep(seconds) {
  var timeToSleep = seconds * 1000
  return new Promise((resolve) => setTimeout(resolve, timeToSleep));
};

ask anything Im more then happy to help
 
Is that script handling recaptchas placed in iframes?
 
Nice! Will try it with death by captcha and let you guys know how it works.
 
Back
Top