如何避免Puppeteer被检测
如今,网站使用可以检测爬虫的反机器人系统。确保无缝抓取过程的最佳方法是使用适当的屏蔽方法,例如无头浏览器。
Puppeteer 是一个无头的 Chrome,能够模拟真实的用户行为,以避免在网络抓取时出现反机器人。那么你如何去做呢?
在本文中,我们将讨论在抓取时避免被 Puppeteer 检测到的最佳方法。但在那之前…
什么是Puppeteer?
Puppeteer是一个 Node.js 库,它以编程方式为 Chromium 无头浏览器提供高级 API。
您可以使用 npm 或 Yarn 轻松安装它,它的主要优点之一是它能够访问和操作 DevTools 协议。
反机器人可以检测到 Puppeteer 吗?
是的,这些反机器人能够检测像 Puppeteer 这样的无头浏览器。
让我们通过尝试抓取NowSecure的快速抓取示例来证明这一点。这是一个有机器人检查测试的网站,告诉你是否通过了保护。
为此,我们将继续安装Node.js,完成后,我们将运行以下基本命令代码来安装 Puppeteer。
npm install puppeteer
接下来,我们将创建一个 JavaScript 文件index.js
并使用 Node.js 运行该文件node index.js
,如下所示:
const puppeteer = require('puppeteer'); (async () => { // Initiate the browser const browser = await puppeteer.launch(); // Create a new page with the default browser context const page = await browser.newPage(); // Setting page view await page.setViewport({ width: 1280, height: 720 }); // Go to the target website await page.goto('https://nowsecure.nl/'); // Wait for security check await page.waitForTimeout(30000); // Take screenshot await page.screenshot({ path: 'image.png', fullPage: true }); // Closes the browser and all of its pages await browser.close(); })();
所以这就是我们在那个例子中所做的:我们使用基本的 Puppeteer 设置来创建一个新的浏览器页面并访问目标网站。然后,我们在安全检查后截屏。
从结果可以看出,我们没有通过检查,无法阻止网页上的 Puppeteer 检测。
使用 Puppeteer 避免检测的六个技巧
确保爬行过程顺畅的最佳方法之一是避免 Puppeteer 机器人检测。以下是防止 Puppeteer 检测并避免在抓取时被阻止的方法:
1.使用代理
最广泛采用的反机器人策略之一是 IP 跟踪,其中机器人检测系统跟踪网站的请求。当一个IP在短时间内发出很多请求时,反机器人可以检测到Puppeteer scraper。
为避免在 Puppeteer 中被检测到,您可以使用代理,它在用户和互联网之间提供网关。所以当一个请求被发送到服务器时,它被路由到代理,然后响应数据被发送给我们。
为此,我们可以args
在启动 Puppeteer 时向参数添加代理,如下所示:
const puppeteer = require('puppeteer'); const proxy = ''; // Add your proxy here (async () => { // Initiate the browser with a proxy const browser = await puppeteer.launch({args: ['--proxy-server=${proxy}']}); // ... continue as before })();
您的 Puppeteer 抓取工具现在可以在抓取网页时避免机器人检测。
2. 标题
标头包含有关 HTTP 请求的上下文和元数据信息。它标识该工具是普通网络浏览器还是机器人。您可以通过在 HTTP 请求中包含正确的标头来帮助防止检测。
由于 PuppeteerheadlessChrome
默认情况下工作,您可以通过添加自定义标头(如 User-Agent)来更进一步。它是网络抓取中使用的流行标头,它标识请求的应用程序、操作系统、供应商和版本。
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Add Headers await page.setExtraHTTPHeaders({ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'upgrade-insecure-requests': '1', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', 'accept-encoding': 'gzip, deflate, br', 'accept-language': 'en-US,en;q=0.9,en;q=0.8' }); // ... continue as before })();
在 Puppeteer 中添加标题有多种方法,但最简单的方法是在打开新页面时添加它。
3.限制请求
如前所述,反机器人可以通过发送的请求数量来跟踪用户的活动。而且由于普通用户不会每秒发送数百个请求,因此限制请求数量并在请求之间休息有助于避免 Puppeteer 检测。
为此,您可以使用 来.setRequestInterception()
限制 Puppeteer 中呈现的资源。
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Limit requests await page.setRequestInterception(true); page.on('request', async (request) => { if (request.resourceType() == 'image') { await request.abort(); } else { await request.continue(); } }); // ... continue as before })();
通过设置.setRequestInterception() = true
,我们忽略了 Puppeteer 对图像的请求。这样我们就可以限制请求了。另外,我们将获得更快的抓取器,因为加载和等待的资源更少。
4.模仿用户行为
机器学习系统研究所有用户行为并将机器人行为与用户行为进行比较。模仿这种行为有助于绕过机器人检测器。
实现此目的的一种方法是在单击或导航到 Puppeteer 中的新网页之前随机等待一段时间。例如,这个简单的函数会生成 5 到 12 秒之间的随机时间。
page.waitForTimeout
在打开新标签页之前使用生成的时间。
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Wait for a random time before navigating to a new web page await page.waitForTimeout((Math.floor(Math.random() * 12) + 5) * 1000) // ... continue as before })();
5. Puppeteer-隐形
stealth 插件对 Puppeteer 抓取工具很有帮助,因为它提供了与 Puppeteer 的 API 相当的 API。通过消除 Headless Chrome 和真正的 Chrome 浏览器之间浏览器指纹的微小差异,它可以隐藏浏览器的无头状态。
让我们看看如何使用 Puppeteer-Stealth 来防止检测!
第 1 步:安装 Puppeteer-Stealth
您可以使用以下命令代码执行此操作:
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
第 2 步:配置 Puppeteer-Stealth
要配置 puppeteer-stealth,请创建一个名为的新 JavaScript 文件index.js
并添加以下代码:
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 pupputeer-stealth puppeteer.launch({ headless:false, executablePath: executablePath() }).then(async browser => {
这是上面代码中发生的事情:
首先,我们导入了puppeteer
一个puppeteer-extra
围绕 Puppeteer 的轻量级包装器。然后,我们还导入puppeteer-extra-plugin-stealth
以避免 Puppeteer 检测。它与 一起使用puppeteer.use(pluginStealth())
。
puppeteer
保存在executablePath
. 这会告知puppeteer-stealth
代码将在何处执行。最后,我们启动了 Puppeteer,并提供了headless:false
查看浏览器中发生的情况的选项。
第 3 步:截图
puppeteer.launch({ headless:false, executablePath: executablePath() }).then(async browser => { // Create a new page const page = await browser.newPage(); // Setting page view await page.setViewport({ width: 1280, height: 720 }); // Go to the website await page.goto('https://nowsecure.nl/'); // Wait for security check await page.waitForTimeout(10000); await page.screenshot({ path: 'image.png', fullPage: true }); await browser.close(); });
启动浏览器后,使用创建一个新页面await browser.newPage()
并设置浏览器视图。Puppeteer 被指示访问目标网站并等待十秒钟进行安全检查。之后截图,关闭浏览器。
恭喜!您已阻止 Puppeteer 机器人检测。让我们更进一步,抓取页面。
第 4 步:抓取页面😀
找到您要抓取的每个元素的选择器,为此,右键单击一个元素并选择“检查”。这将打开 Chrome DevTools,您可以从“元素”选项卡中获取选择器。
复制选择器并使用每个选择器获取其文本。该querySelector
方法非常适合此目的:
await page.goto('https://nowsecure.nl/'); await page.waitForTimeout(10000); // Get title text title = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > header > div > h3').textContent; }); // Get message text msg = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > main > h1').textContent; }); // get state text state = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > main > p:nth-child(2)').textContent; }); // print out the results console.log(title, 'n', msg, 'n', state); await browser.close(); });
该脚本使用该.textContent
方法获取每个元素的文本。可以对每个元素重复相同的过程并将其保存到变量中。在此处运行代码后,输出应如下所示:
您已经解决了主要问题并成功阻止了 Puppeteer 机器人检测。这是完整的代码应该是什么:
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 pupputeer-stealth puppeteer.launch({ headless:false, executablePath: executablePath() }).then(async browser => { // Create a new page const page = await browser.newPage(); // Setting page view await page.setViewport({ width: 1280, height: 720 }); // Go to the website await page.goto('https://nowsecure.nl/'); // Wait for security check await page.waitForTimeout(10000); // Get title text title = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > header > div > h3').textContent; }); // Get message text msg = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > main > h1').textContent; }); // get state text state = await page.evaluate(() => { return document.querySelector('body > div.nonhystericalbg > div > main > p:nth-child(2)').textContent; }); // print out the results console.log(title, 'n', msg, 'n', state); await browser.close(); });
Puppeteer-Stealth 的局限性
Puppeteer-Stealth 是避免机器人检测的一个很好的解决方案,但它有局限性:
- 它无法避免高级反机器人。
- Puppeteer 在无头模式下工作,因此很难扩展和抓取大量数据。
- 很难调试 Puppeteer 等无头浏览器。
不幸的是,Puppeteer-Stealth 无法对抗具有高级反机器人程序的网站。例如,我们尝试用它来抓取Okta:
// same as before puppeteer.launch({ headless:true, executablePath: executablePath() }).then(async browser => { const page = await browser.newPage(); await page.setViewport({ width: 1920, height: 1080 }); // Go to the website await page.goto('https://okta.com/'); // Wait for security check await page.waitForTimeout(10000); await page.screenshot({ path: 'image.png', fullPage: true }); await browser.close(); });
我们直接被挡住了!幸运的是,我们有一个可以绕过高级反机器人的解决方案:ZenRows。这是我们避免被发现的下一个提示。
6.ZenRows
ZenRows是一种一体化的网络抓取工具,它使用单个 API 调用来处理所有反机器人绕过。它有助于旋转代理、无头浏览器和验证码。
结论
有多种方法可以避免使用 Puppeteer 进行检测,我们在本文中讨论了最好和最简单的方法。
您可以使用代理、标头、限制请求或 Puppeteer-Stealth 来完成工作,但有一些限制。这些方法的共同问题是它们在绕过高级反机器人程序时会失败。