如何使用Puppeteer绕过验证码

如何使用Puppeteer绕过验证码

CAPTCHA 是一个重要的网络抓取障碍,可以让人类通过并阻止机器人。但今天,我们将了解Puppeteer如何帮助您克服该技术,以及您可以做些什么来使其更有效。

简而言之,使用 Puppeteer 绕过验证码的方法有:

  1. 使用付费求解器。
  2. 实施免费求解器。
  3. 面具基地傀儡师。
  4. 掩盖你的要求。

Puppeteer 可以破解验证码吗?

完整的答案是有两种主要方法:避免和解决它。

由于挑战主要基于可疑活动而提示,并且无头浏览器帮助网络抓取工具模仿人类行为,Puppeteer 帮助我们避免它。但是,我们需要为基础 Puppeteer 增压以提高其成功率。

然而,最直接的场景是提示挑战时,你只想解决。为此,您必须使用带有 Puppeteer 的第三方求解器。

本教程将涵盖这两种方法,以帮助您使用 Puppeteer 绕过 CAPTCHA。

假设您在抓取数据时遇到受验证码保护的表单,需要解决它。在这里,我们将使用 2Captcha,这是一种基于 API 的服务,它雇用人类来解决问题并返回答案。

2Captcha 的演示页面是我们将用来说明如何从头开始将求解器与 Puppeteer 集成的沙箱。

medium_2captcha_demo_5c743a494b

首先,在 2Captcha 上注册以获取 API 密钥。然后,安装 Puppeteer 和requests模块。

npm install puppeteer request

现在,让我们编写一个脚本来打开您要抓取的网站,截取验证码的屏幕截图并将其发送到服务。

const puppeteer = require('puppeteer');
const request = require('request');
 
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
 
  // navigate to the page with the CAPTCHA
  await page.goto('https://2captcha.com/demo/normal');
 
  // take a screenshot of the CAPTCHA
  const screenshot = await page.screenshot();
 
  // convert the screenshot to a base64 encoded string
  const image = new Buffer(screenshot).toString('base64');
 
  // send the image to the 2Captcha API
  request.post({
    url: 'http://2captcha.com/in.php',
    formData: {
      key: 'your_2captcha_api_key',
      method: 'base64',
      body: image
    }
  }, async (error, response, body) => {
    if (error) {
      console.error(error);
    } 

我们将使用 ID 捕获 API 响应,如下所示。

// get the CAPTCHA ID from the 2Captcha API response
const captchaId = body.split('|')[1];

// request the CAPTCHA solution from the 2Captcha API
request.get({
  url: `http://2captcha.com/res.php?key=your_2captcha_api_key&action=get&id=${captchaId}`
}, (error, response, body) => {
  if (error) {
    console.error(error);
  }
});

一旦我们得到解决方案,我们就可以把它放在页面上来解决测试。

// get the CAPTCHA solution from the 2Captcha API response
const captchaSolution = body.split('|')[1];

// use the CAPTCHA solution in your Puppeteer script
await page.type('#captcha-input', captchaSolution);
await page.click('#submit-button');

这就是我们的完整脚本的样子:

const puppeteer = require('puppeteer');
const request = require('request');
 
(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
 
  // navigate to the page with the CAPTCHA
  await page.goto('https://example.com/captcha');
 
  // take a screenshot of the CAPTCHA
  const screenshot = await page.screenshot();
 
  // convert the screenshot to a base64 encoded string
  const image = new Buffer(screenshot).toString('base64');
 
  // send the image to the 2Captcha API
  request.post({
    url: 'http://2captcha.com/in.php',
    formData: {
      key: 'your_2captcha_api_key',
      method: 'base64',
      body: image
    }
  }, async (error, response, body) => {
    if (error) {
      console.error(error);
    } else {
      // get the CAPTCHA ID from the 2Captcha API response
      const captchaId = body.split('|')[1];
 
      // request the CAPTCHA solution from the 2Captcha API
      request.get({
        url: `http://2captcha.com/res.php?key=your_2captcha_api_key&action=get&id=${captchaId}`
      }, async (error, response, body) => {
        if (error) {
          console.error(error);
        } else {
          // get the CAPTCHA solution from the 2Captcha API response
          const captchaSolution = body.split('|')[1];
 
          // use the CAPTCHA solution in your Puppeteer script
          await page.type('#captcha-input', captchaSolution);
          await page.click('#submit-button');
        }
        await browser.close();
      });
    }
  });
})();

medium_2captcha_demo_target_82c30e5008

你使用 Puppeteer 和 2Captcha 解决了你的第一个验证码。

问题是这项服务在大规模抓取时变得昂贵且缓慢。此外,还有一些类型的验证码无法通过 API 求解器解决。

方法#2:实施免费求解器插件

puppeteer-extra-plugin-recaptcha是一个免费的开源模块,可自动解决市场上最流行的两种反机器人技术 reCAPTCHA 和 hCAPTCHA。此外,它还带有 2Captcha 集成,因此您可以在免费模块不够用的情况下使用它。

我们将使用相同的演示页面作为示例目标。

要开始,请安装puppeteer-extrarecaptcha.

npm install puppeteer puppeteer-extra puppeteer-extra-plugin-recaptcha

导入库并提供您的 2Captcha API 密钥作为令牌。

const puppeteer = require('puppeteer-extra')
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
 
// Use the RecaptchaPlugin with the specified provider (2captcha) and token
puppeteer.use(
  RecaptchaPlugin({
    provider: {
      id: '2captcha',
      token: 'XXXXXXX' 
    },
    visualFeedback: true // Enable visual feedback (colorize reCAPTCHAs)
  })
)

接下来,导航到您的目标网页并使用该方法初始化求解page.solveRecaptchas()

// Launch a headless browser instance
puppeteer.launch({ headless: true }).then(async browser => {
  // Create a new page
  const page = await browser.newPage()
 
  // Navigate to a page containing a reCAPTCHA challenge
  await page.goto('https://2captcha.com/demo/recaptcha-v2')
 
  // Automatically solve the reCAPTCHA challenge
  await page.solveRecaptchas()

现在,等待解决方案并单击提交按钮。

// Wait for the navigation and click the submit button
await Promise.all([
await Promise.all([
  page.waitForNavigation(),
  page.click(`#recaptcha-demo-submit`)
])

完整的代码应该是这样的:

const puppeteer = require('puppeteer-extra')
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
 
// Use the RecaptchaPlugin with the specified provider (2captcha) and token
puppeteer.use(
  RecaptchaPlugin({
    provider: {
      id: '2captcha',
      token: 'XXXXXXX' 
    },
    visualFeedback: true // Enable visual feedback (colorize reCAPTCHAs)
  })
)
 
// Launch a headless browser instance
puppeteer.launch({ headless: true }).then(async browser => {
  // Create a new page
  const page = await browser.newPage()
 
  // Navigate to a page containing a reCAPTCHA challenge
  await page.goto('https://2captcha.com/demo/recaptcha-v2')
 
  // Automatically solve the reCAPTCHA challenge
  await page.solveRecaptchas()
 
  // Wait for the navigation and click the submit button
  await Promise.all([
    page.waitForNavigation(),
    page.click(`#recaptcha-demo-submit`)
  ])
 
  // Take a screenshot of the response page
  await page.screenshot({ path: 'response.png', fullPage: true })
 
  // Close the browser
  await browser.close()
})

这是结果:

medium_2captcha_demo_bypass_0fbfdd5baf

但是,将 CAPTCHA 求解器与 Puppeteer 一起使用主要用于测试目的,而不是大规模抓取,因为它很快就会变得过于昂贵和缓慢。出于这个原因,我们将专注于通过更好地掩盖 Puppeteer 来避免挑战的出现(并在遇到挑战时重新尝试我们的请求)。

方法#3:通过隐身来增强 Puppeteer 以绕过验证码

如前所述,使用 Puppeteer 绕过验证码有两种主要方法:解决和避免。是时候探索第二种方法,让你的爬虫无法被发现了。

Puppeteer Stealth是一个插件,包含多项功能,可解决网站用于检测无头 Chrome 的大多数方法。让我们看看它是如何通过抓取OpenSea来做到这一点的,OpenSea 是一个受反机器人保护的网站,当请求不符合其自然用户阈值时,该网站会显示验证码。

要开始,您必须安装puppeteer-extrapuppeteer-extra-plugin-stealth

npm install puppeteer-extra puppeteer-extra-plugin-stealth

然后,导入模块,将库保存到executablePath,并启用puppeteer-stealth使用puppeteer.use(pluginStealth())

const puppeteer = require("puppeteer-extra"); 
const pluginStealth = require("puppeteer-extra-plugin-stealth"); 
 
//save to executable path
const { executablePath } = require("puppeteer"); 
 
// Use stealth 
puppeteer.use(pluginStealth());

接下来的步骤包括设置视口、导航到页面 URL、等待加载以及截取屏幕截图以跟踪该过程。

// Launch puppеteer-stealth 
puppeteer.launch({ executablePath: executablePath() }).then(async browser => { 
    // Create a new page 
    const page = await browser.newPage(); 
 
    // Set page view 
    await page.setViewport({ width: 1280, height: 720 }); 
 
    // navigate to the website 
    await page.goto("https://www.opensea.io/"); 
 
    // Wait for page to load
    await page.waitForTimeout(1000); 
 
    // Take a screenshot 
    await page.screenshot({ path: "image.png" }); 
 
    // Close the browser 
    await browser.close(); 
});

这是完整的代码:

const puppeteer = require("puppeteer-extra"); 
 
// Add stealth plugin and use defaults 
const pluginStealth = require("puppeteer-extra-plugin-stealth"); 
const { executablePath } = require("puppeteer"); 
 
// Use stealth 
puppeteer.use(pluginStealth()); 
 
// Launch puppeteer-stealth 
puppeteer.launch({ executablePath: executablePath() }).then(async browser => { 
    // Create a new page 
    const page = await browser.newPage(); 
 
    // Set page view 
    await page.setViewport({ width: 1280, height: 720 }); 
 
    // navigate to the website 
    await page.goto("https://www.opensea.io/"); 
 
    // Wait for page to load
    await page.waitForTimeout(1000); 
 
    // Take a screenshot 
    await page.screenshot({ path: "image.png" }); 
 
    // Close the browser 
    await browser.close(); 
});

见下文。

medium_opensea_bypass_d224aeaeba

恭喜!您离成为网络抓取专家又近了一步。你只是让你的蜘蛛更不易被发现。

但是,更高级的网站保护可以检测到 Puppeteer Stealth。让我们通过在G2 的产品页面上运行相同的脚本来确认:

medium_g2_bypass_a9ce045e34

到目前为止,基础 Puppeteer、puppeteer-extra-plugin-recaptcha 和 2Captcha 并没有解决抓取可扩展性问题。接下来我们将看看最终的解决方案。

方法 #4:ZenRows 的最佳验证码绕过

Puppeteer 是一个强大的工具,但如上面的示例所示,它有其自身的一系列限制。我们要不要找个替代品?

ZenRows 是一款一体化工具,可在单个 API 调用中实现大规模抓取,包括无头浏览器和反验证码功能。让我们看看它的实际效果!我们将尝试抓取 Puppeteer Stealth 失败的 G2 页面。

要开始使用,请注册您的免费 API 密钥。

您将进入 Request Builder,您必须在其中粘贴https://www.g2.com/products/asana/reviews为目标 URL 并激活Antibot,JavaScript RenderingPremium Proxy。在这种情况下,我们将使用 SDK 模式。

medium_zenrows_api_922db7ee55

现在,切换到您的代码编辑器并使用npm命令安装 ZenRows。

npm install zenrows

最后,将提供的代码粘贴到 Request Builder 和console.log()响应中。

const { ZenRows } = require("zenrows");
 
(async () => {
    const client = new ZenRows("YOUR_API_KEY");
    const url = "https://www.g2.com/products/asana/reviews";
 
    try {
        const { data } = await client.get(url, {
            "js_render": "true",
            "antibot": "true",
            "premium_proxy": "true"
        });
        console.log(data);
    } catch (error) {
        console.error(error.message);
        if (error.response) {
            console.error(error.response.data);
        }
    }
})();

这是成功的结果:

<!DOCTYPE html><html class=" cors history json svg es6object promises cssgradients fontface csstransitions"><head><style type="text/css">.turbo-progress-bar {
  position: fixed;
  display: block;
  top: 0;
  left: 0;
  height: 3px;
  background: #0076ff;
  z-index: 9999;
  transition:
    width 300ms ease-out,
    opacity 150ms 150ms ease-in;
  transform: translate3d(0, 0, 0);
}
</style><meta charset="utf-8"><link href="https://www.g2.com/assets/favicon-fdacc4208a68e8ae57a80bf869d155829f2400fa7dd128b9c9e60f07795c4915.ico" rel="shortcut icon" type="image/x-icon"><title>Business Software and Services Reviews | G2</title><meta content="78D210F3223F3CF585EB2436D17C6943" name="msvalidate.01"><meta content="width=device-width, initial-scale=1" name="viewport"><meta content="GNU Terry Pratchett" http-equiv="X-Clacks-Overhead"><meta content="ie=edge" http-equiv="x-ua-compatible"><meta content="en-us" http-equiv="content-language"><meta content="website" property="og:type"><meta content="G2" property="og:site_name"><meta content="@G2dotcom" name="twitter:site"><meta content="Business Software and Services Reviews | G2" property="og:title"><meta content="https://www.g2.com/" property="og:url"><meta content="Compare the best business software and services based on user ratings and social data. Reviews for CRM, ERP, HR, CAD, PDM and Marketing software." property="og:description">

结论

一些使用 Puppeteer 绕过 CAPTCHA的解决方案包括集成求解器和更好地屏蔽浏览器,但它们在很多情况下都无法交付并且无法扩展。对于成功的数据提取项目,您需要一个可扩展且高效的解决方案。

类似文章