npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

puppeteer-extra-plugin-recaptcha-anti-captcha

v1.0.3

Published

A puppeteer-extra plugin that implements Anti-Captcha support for puppeteer-extra-plugin-recaptcha.

Downloads

18

Readme

Anti-Captcha provider for puppeteer-extra-plugin-recaptcha!

This is a plugin for puppeteer-extra-plugin-recaptcha that implements Anti-Captcha provider to the solver.

You can still use the 2CAPTCHA provider

Gratitude

  • Thanks to berstend for the original plugin

Install

npm install puppeteer-extra-plugin-recaptcha-anti-captcha

If this is your first puppeteer-extra plugin here's everything you need:

npm install puppeteer puppeteer-extra puppeteer-extra-plugin-recaptcha-anti-captcha

Usage

The plugin essentially provides a mighty page.solveRecaptchas() method that does everything needed automagically.

// puppeteer-extra is a drop-in replacement for puppeteer,
// it augments the installed puppeteer with plugin functionality
const puppeteer = require('puppeteer-extra')

// add recaptcha plugin and provide it your anti-captcha token (= their apiKey)
// anti-captcha is the builtin solution provider but others would work as well.
// Please note: You need to add funds to your anti-captcha account for this to work
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha-anti-captcha')
puppeteer.use(
  RecaptchaPlugin({
    provider: {
      id: 'antigate',   // or '2captcha'
      token: 'XXXXXXX' // REPLACE THIS WITH YOUR OWN 2CAPTCHA API KEY OR ANTI-CAPTCHA API KEY ⚡
    },
    visualFeedback: true // colorize reCAPTCHAs (violet = detected, green = solved)
  })
)

// puppeteer usage as normal
puppeteer.launch({ headless: true }).then(async browser => {
  const page = await browser.newPage()
  await page.goto('https://www.google.com/recaptcha/api2/demo')

  // That's it, a single line of code to solve reCAPTCHAs 🎉
  await page.solveRecaptchas()

  await Promise.all([
    page.waitForNavigation(),
    page.click(`#recaptcha-demo-submit`)
  ])
  await page.screenshot({ path: 'response.png', fullPage: true })
  await browser.close()
})

Options

interface PluginOptions {
  /** Visualize reCAPTCHAs based on their state */
  visualFeedback: boolean // default: true
  /** Throw on errors instead of returning them in the error property */
  throwOnError: boolean // default: false
  /** Only solve captchas and challenges visible in the browser viewport */
  solveInViewportOnly: boolean // default: false
  /** Solve scored based captchas with no challenge (e.g. reCAPTCHA v3) */
  solveScoreBased: boolean // default: false
  /** Solve invisible captchas that have no active challenge */
  solveInactiveChallenges: boolean // default: false
}

What about invisible reCAPTCHAs?

  • Invisible reCAPTCHAs are supported. They're basically used to compute a score of how likely the user is a bot. Based on that score the site owner can block access to resources or (most often) present the user with a reCAPTCHA challenge (which this plugin can solve). The stealth plugin might be of interest here, as it masks the usage of puppeteer.
  • Technically speaking the plugin supports: reCAPTCHA v2, reCAPTCHA v3, invisible reCAPTCHA, hCaptcha, invisible hCaptcha. All of those (multiple as well) are solved when page.solveRecaptchas() is called.

When should I call page.solveRecaptchas()?

  • reCAPTCHAs will be solved automatically whenever they are visible (aka their "I'm not a robot" iframe in the DOM). It's your responsibility to do any required actions to trigger the captcha being shown, if needed.
    • Note about "invisible" versions of reCAPTCHA/hCaptchas: They don't feature a visible checkbox iframe, the plugin will then solve any open challenge popups instead. :-)
  • If you summon the plugin immediately after navigating to a page it's got your back and will wait automatically until the reCAPTCHA script (if any) has been loaded and initialized.
  • If you call page.solveRecaptchas() on a page that has no reCAPTCHAs nothing bad will happen (😄) but the promise will resolve and the rest of your code executes as normal.
  • After solving the reCAPTCHAs the plugin will automatically detect and trigger their optional callback. This might result in forms being submitted and page navigations to occur, depending on how the site owner implemented the reCAPTCHA.

Defaults

By default the plugin will never throw, but return any errors silently in the { error } property of the result object. You can change that behaviour by passing throwOnError: true to the initializier and use try/catch blocks to catch errors.

For convenience and because it looks cool the plugin will "colorize" reCAPTCHAs depending on their state (violet = detected and being solved, green = solved). You can turn that feature off by passing visualFeedback: false to the plugin initializer.

Troubleshooting

Solving captchas in iframes

By default the plugin will only solve reCAPTCHAs showing up on the immediate page. In case you encounter captchas in frames the plugin extends the Puppeteer.Frame object with custom methods as well:

// Loop over all potential frames on that page
for (const frame of page.mainFrame().childFrames()) {
  // Attempt to solve any potential captchas in those frames
  await frame.solveRecaptchas()
}

In addition you might want to disable site isolation, so puppeteer is able to access cross-origin iframes:

puppeteer.launch({
  args: [
    '--disable-features=IsolateOrigins,site-per-process,SitePerProcess',
    '--flag-switches-begin --disable-site-isolation-trials --flag-switches-end'
  ]
})

Solving captchas in pre-existing browser pages

In case you're not using browser.newPage() but re-use the existing about:blank tab (which is not recommended for various reasons) you will experience a page.solveRecaptchas is not a function error, as the plugin hasn't hooked into this page yet. As a workaround you can manually add existing pages to the lifecycle methods of the plugin:

const recaptcha = RecaptchaPlugin()
const pages = await browser.pages()
for (const page in pages) {
  // Add plugin methods to existing pages
  await recaptcha.onPageCreated(page)
}

Tips

  • Make sure to use debug logging if something is not working right or when reporting issues.
  • Check for ignored captchas in the filtered array in case a captcha you intend to solve is being ignored, filtered captchas will state the reason why they have been ignored (or better: which plugin option is responsible)
  • Keep in mind that by default the plugin will only solve "active" captchas (the means a visible checkbox or an active challenge popup). In extreme cases (like a very weird or super slow loading site) you can help the plugin by making sure the captcha you intend to solve is there before calling page.solveRecaptchas:
await page.waitForSelector('iframe[src*="recaptcha/"]')
await page.solveRecaptchas()