在Puppeteer中进行网页搜刮时如何处理验证码?

时间:2019-04-03 10:58:52

标签: javascript web-scraping captcha puppeteer

我正在使用Puppeteer进行Web爬网,并且我刚刚注意到,有时我试图抓取的网站会要求输入验证码,原因是我在计算机上进行的访问次数很多。验证码形式如下:

captcha

因此,我将需要有关如何处理此问题的帮助。我一直在考虑将验证码表单发送到客户端,因为我使用Express和EJS来将值发送到我的索引网站,但是我不知道Puppeteer是否可以发送类似的内容。

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

您应该使用以下组合:

  • 如果目标网站提供API,请使用API​​。这是最合法的方式。
  • 增加两次抓取请求之间的等待时间,不要将大量请求发送到服务器。
  • 经常更改/轮换IP。
  • 更改用户代理,浏览器视口大小和指纹。
  • 对验证码使用第三方解决方案。
  • 自己解决验证码,请检查Thomas Dondorf的答案。基本上,您需要等待验证码出现在另一个浏览器上,然后从那里解决它。第三方解决方案可以为您完成此任务。

免责声明:请勿使用反验证码插件/服务来滥用资源。资源很昂贵。


基本上,这个想法是使用反验证码服务(例如(2captcha))来处理持久的重新验证。

您可以使用berstend的名为puppeteer-extra-plugin-recaptcha的插件。

// 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 2captcha token
// 2captcha is the builtin solution provider but others work as well.
const RecaptchaPlugin = require('puppeteer-extra-plugin-recaptcha')
puppeteer.use(
  RecaptchaPlugin({
    provider: { id: '2captcha', token: 'XXXXXXX' },
    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()
})

PS:

  • 还有其他插件,即使我做了一个非常简单的插件,因为即使对于像我这样的人,验证码也越来越难解决。您可以阅读代码here
  • 我与2Captcha或上述任何其他第三方服务无关。
  • 我创建了自己的解决方案,与Thomas Dondorf的其他答案类似,但是由于Captcha变得越来越荒谬,并且我没有解决问题的精神,因此很快就放弃了。

答案 1 :(得分:2)

这是一个reCAPTCHA(版本2,请检出demos here),因为页面所有者不希望您自动抓取页面而显示给您。

您的选择如下:

选项1:停止抓取或尝试使用官方API

由于页面所有者不希望您爬网该页面,因此您只需遵守该决定并停止爬网即可。也许有一个文档化的API可供您使用。

选择2:自动/外包验证码

整个行业都有人(通常在发展中国家)为其他人的机器人填充验证码。我不会链接到任何特定的网站,但是您可以从 Md查看其他答案。有关该主题的更多信息,或搜索验证码求解器

选项3:自己解决验证码

为此,让我解释一下reCAPTCHA的工作原理以及使用该页面访问页面时会发生什么情况。


reCAPTCHA(v2)的工作原理

每个页面都有一个ID,您可以通过查看源代码来检查ID,例如:

<div class="g-recaptcha form-field" data-sitekey="ID_OF_THE_WEBSITE_LONG_RANDOM_STRING"></div>

加载reCAPTCHA代码后,它将在表单中添加一个 response 文本区域,不带任何值。看起来像这样:

<textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="... display: none;"></textarea>

解决挑战后,提交表单时,reCAPTCHA会在此文本字段中添加一个很长的字符串(稍后可以由后端的server / reCAPTCHA服务检查)。


如何自己解决验证码

通过复制textarea字段的值,您可以将“已解决的挑战”从一个浏览器转移到另一个浏览器(这也是为您提供的解决服务)。整个过程如下所示:

  1. 检测页面是否在“搜寻中的”浏览器中使用reCAPTCHA(例如检查.g-recaptcha
  2. 以无头模式打开另一个具有相同URL的浏览器
  3. 自己解决验证码
  4. 从以下位置读取值:document.querySelector('#g-recaptcha-response').value
  5. 将该值放入第一个浏览器:document.querySelector('#g-recaptcha-response').value = '...'
  6. 提交表格

其他信息/阅读

由于这是机器人创建者和Google检测算法之间的猫捉老鼠游戏,因此Google并没有太多公开信息说明reCAPTCHA的工作原理,但是在线上有一些资源提供了更多信息:

  • Official docs from Google:很明显,他们只是在解释基本知识,而不是解释其在背后的工作方式。
  • InsideReCaptcha:这是2014年以来的一个项目,试图对reCAPTCHA进行“反向工程”。尽管这已经很老了,但是页面上仍然有很多有用的信息。
  • Another question on stackoverflow:这个问题包含有关reCAPTCHA的一些有用信息,但也包含许多关于如何欺骗reCAPTCHA的推测性(而且很可能是过时的)方法。

答案 2 :(得分:1)

可以使用代理服务器,以便目标站点不会检测到来自单个IP地址的响应负载。

(翻译成Google翻译)

答案 3 :(得分:1)

我尝试了@Thomas Dondorf 的建议,但我认为“如何自己解决验证码”部分中描述的步骤的问题在于验证码的令牌仅有效一次。 我将在下面详细解释所有内容。

我在用什么

我使用第一个浏览器(无法解决验证码的浏览器)Google Chrome,以及第二个浏览器(我解决验证码并获取令牌的浏览器)Firefox。

步骤

  1. 我在这个网站上手动解决了验证码https://recaptcha-demo.appspot.com/recaptcha-v2-checkbox.php
  2. 我在 google chrome 控制台中输入以下代码 document.querySelector('#g-recaptcha-response').value,但出现错误(VM22:1 Uncaught TypeError: Cannot read property 'value' of null at :1:48),所以我只是通过在 Google Chrome 中打开 Elements 并使用 CTRL+F 搜索 g-recaptcha-response 来搜索令牌
  3. 我复制了 recaptcha 的令牌(在以绿色突出显示的文本之后,这是一张显示令牌所在位置的图像)here is the part of the code of the webpage that has the token
  4. 我在 firefox 控制台中键入以下代码 document.querySelector('#g-recaptcha-response').value = '...',用刚刚复制的 recaptcha 令牌替换“...”
  5. 我收到以下错误error,如果您随后单击 documentation linked,您会看到该错误是由于令牌只能使用一次这一事实,并且它当然已经用于您刚刚解决的 CAPTCHA 以获取令牌本身(因此似乎令牌的唯一目标是说已经解决了 CAPTCHA,这似乎是一种防止重播的防御措施攻击,如 official documentation of the recaptcha 中所述。