我正在使用Puppeteer进行网页抓取,我刚刚注意到有时候,由于我从我的计算机上进行的访问量过多,所以我尝试抓取的网站要求输入验证码。验证码表单看起来像这样:
因此,我需要帮助处理这个问题。我一直在考虑将验证码表单发送到客户端,因为我使用Express和EJS以便将值发送到我的主页,但我不知道Puppeteer是否可以发送这样的内容。
有什么想法吗?
有什么想法吗?
这是一个reCAPTCHA (版本2,可以在这里查看演示),它会显示给您,因为页面所有者不希望您自动抓取该页面。
您有以下选项:
由于页面所有者不希望您爬取该页面,您可以尊重该决定并停止爬取。也许有一份记录的API可供您使用。
存在一个整个行业,其中人们(通常位于发展中国家)为其他人的机器人填写验证码。我不会链接到任何特定的网站,但您可以查看Md. Abu Taher 的另一个答案以获取更多信息,或搜索 captcha solver。
为此,让我解释一下reCAPTCHA的工作原理以及当您访问使用它的页面时会发生什么。
每个页面都有一个ID,您可以通过查看源代码来检查,例如:
<div class="g-recaptcha form-field" data-sitekey="ID_OF_THE_WEBSITE_LONG_RANDOM_STRING"></div>
当reCAPTCHA代码加载时,它将在表单中添加一个没有值的响应文本区域。它将看起来像这样:当reCAPTCHA代码加载时,它将在表单中添加一个没有值的响应文本区域。它将看起来像这样:
<textarea id="g-recaptcha-response" name="g-recaptcha-response" class="g-recaptcha-response" style="... display: none;"></textarea>
在您解决了验证码之后,reCAPTCHA将在表单提交时向该文本字段添加一个非常长的字符串(之后可以由服务器/后端的reCAPTCHA服务进行检查)。
通过复制textarea
字段的值,您可以将“已解决的挑战”从一个浏览器传输到另一个浏览器(这也是求解服务为您提供的内容)。完整的过程如下:
.g-recaptcha
)document.querySelector('#g-recaptcha-response').value
document.querySelector('#g-recaptcha-response').value = '...'
谷歌没有太多关于reCAPTCHA如何工作的公共信息,因为这是机器人创建者和谷歌检测算法之间的猫鼠游戏,但是有一些在线资源提供了更多信息:
您应该采用以下组合方法:
免责声明:请勿滥用反验证码插件/服务来占用资源。资源是昂贵的。
基本上,使用2captcha等反验证码服务来处理持久性reCAPTCHA的想法是很好的。
您可以使用名为puppeteer-extra-plugin-recaptcha
的插件,由berstend提供。
// 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()
})
附注:
document.querySelector('#g-recaptcha-response').value
,但是我得到一个错误(VM22:1未捕获的TypeError:无法读取null的属性'value',
在:1:48),所以我只需通过打开Google Chrome中的Elements并使用CTRL + F搜索g-recaptcha-response
来查找令牌。document.querySelector('#g-recaptcha-response').value = '...'
,将“...”替换为刚刚复制的reCAPTCHA令牌。