如何使用Playwright绕过Cloudflare
即使使用无头浏览器,您的网络抓取工具是否也会被阻止?在本教程中,您将学习如何更好地屏蔽 Playwright 以绕过 Cloudflare。
什么是 Cloudflare
Cloudflare是一家安全和性能优化公司,其服务 Bot Management 是许多抓取工具的噩梦。它是一种 Web 应用程序防火墙 (WAF),大约有 1/5 的互联网站点使用它,可以系统地检测和阻止抓取工具。
Cloudflare 的工作原理
Cloudflare 使用各种方法来比较和区分人类用户和机器人发起的流量,包括:
- 行为分析:它跟踪用户与网站交互的多个特征,例如鼠标移动、点击和页面加载时间。
- IP信誉分析:它根据数据库检查每个请求的IP,看看它是否参与了抓取活动。
- 用户代理 分析:这是一个标识请求网站的浏览器或设备的字符串。抓取工具通常使用 Cloudflare 可以检测到的通用或易于识别的用户代理字符串。
- 验证码 测试:当向网站发出请求时,系统可能会决定测试用户是人类还是机器人。如果用户通过,请求将被允许继续进行。否则就会被屏蔽。
- 请求率分析:此方法涉及监控对网站发出的请求数量并识别自动化机器人的典型模式。例如,机器人通常会在短时间内发出大量请求。
请查看我们的Cloudflare 绕过指南,了解有关这些防御技术的更多信息。
为什么 Base Playwright 不足以绕过 Cloudflare
Base Playwright可能不足以绕过 Cloudflare 的反机器人措施。原因?尽管此浏览器自动化库或其他浏览器自动化库可以模拟类似人类的浏览行为并解决一些挑战,但更先进的技术可能需要绕过额外的工作,例如使用代理和自定义用户代理。
作为证明,让我们使用 NodeJS 设置一个 Playwright 项目,并观察它在绕过 Cloudflare 方面的不足。
步骤#1:确保您的系统上安装了Node.js和 npm。
步骤#2:导航到所需的目录并通过运行以下命令创建一个新项目:
npm init
步骤#3:现在,使用以下命令将 Playwright 作为依赖项安装。
npm install playwright
步骤#4:干得好!现在您已准备好使用 Playwright。在项目目录中创建一个.js
扩展名为 的新文件,例如scraper.js
,并编写一个脚本来访问<https://g2.com>
该文件并对其进行屏幕截图。
const playwright = require("playwright"); async function scraper() { const browser = await playwright.chromium.launch({ headless: true }); const context = await browser.newContext(); const page = await context.newPage(); await page.goto("https://g2.com"); await page.waitForTimeout(1000); await page.screenshot({ path: "screenshot.png", fullPage: true }); await browser.close(); } scraper();
注意:正如您在第四行看到的,我们的抓取工具使用 Chromium 作为浏览器,但您可以选择其他浏览器。
步骤#5:使用以下命令执行完整的代码:
node scraper.js
结果如下
遗憾的是,Playwright 的基本版本被识别为机器人,因此拒绝访问该网站。
在下一节中,我们将探讨几种可帮助您赢得 Cloudflare 的技术。继续阅读!
如何屏蔽Playwright以绕过 Cloudflare
让我们看看处理 Cloudflare 使用的检测方法的几种方法。通常,您需要将它们组合起来才能使您的脚本正常工作。
方法一:模拟人类行为
您可以通过添加随机延迟、滚动和其他与页面的交互来修改我们之前的 Playwright scraper 代码,以使自动浏览器看起来更人性化。
const playwright = require("playwright"); async function getData() { const browser = await playwright.chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); await page.goto("https://books.toscrape.com/"); // Add a random delay of 1 to 5 seconds to simulate human behavior await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 4000 + 1000))); // Scroll the page to load additional content await page.evaluate(() => window.scrollBy(0, window.innerHeight)); // Add another random delay of 1 to 5 seconds await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * 4000 + 1000))); const data = await page.evaluate(() => { const results = []; // Select elements on the page and extract data const elements = document.querySelectorAll(".product_pod"); for (const element of elements) { results.push({ url: element.querySelector("a").href, Name: element.querySelector("h3").innerText, }); } return results; }); console.log(data); await browser.close(); } getData();
方法2:使用代理
抓取网站时,如果短时间内发出过多请求,很容易被禁止。您可以通过使用轮换代理来避免这种情况,这样您就会看起来是不同的用户。
以下是如何使用 Playwright 设置代理。
const playwright = require("playwright"); async function getData() { // Launch a new instance of the browser const browser = await playwright.chromium.launch(); // Create a new context with the specified proxy const context = await browser.newContext({ proxy: { server: 'PROXY_ADDRESS:PROXY_PORT', username: 'PROXY_USERNAME', password: 'PROXY_PASSWORD' } }); // Create a new page within the context const page = await context.newPage(); // Navigate to the target website await page.goto("https://books.toscrape.com/"); // Evaluate the page's content to extract the data we want const data = await page.evaluate(() => { const results = []; // Select the product pods on the page and extract data const elements = document.querySelectorAll(".product_pod"); for (const element of elements) { results.push({ url: element.querySelector("a").href, // Extract the URL of each product Name: element.querySelector("h3").innerText, // Extract the name of each product }); } return results; }); // Log the extracted data to the console console.log(data); // Close the browser await browser.close(); } // Call the getData function to start the process getData();
将PROXY_ADDRESS
和替换PROXY_PORT
为代理服务器的地址和端口。
如有必要,您还可以将PROXY_USERNAME
和替换PROXY_PASSWORD
为用户名和密码。
方法 3:设置自定义用户代理
用户代理包含有关浏览器、操作系统的信息以及有关发出请求的客户端的其他详细信息。为了避免被标记,最好使用类似于常见 Web 浏览器的自定义用户代理,而不是 Playwright 提供的默认值。
看看我们是如何做到的。
const playwright = require("playwright"); async function getData() { const browser = await playwright.chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); // Set custom headers await page.setExtraHTTPHeaders({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', 'Accept-Language': 'en-US,en;q=0.9' }); await page.goto("https://books.toscrape.com/"); const data = await page.evaluate(() => { const results = []; // Select elements on the page and extract data const elements = document.querySelectorAll(".product_pod"); for (const element of elements) { results.push({ url: element.querySelector("a").href, Name: element.querySelector("h3").innerText, }); } return results; }); console.log(data); await browser.close(); } getData();
我们设置了 User-Agent 和一些额外的 HTTP 标头,使请求看起来像是来自使用 Web 浏览器的人类用户。
方法四:解决验证码
您可以使用 Playwright 应用不同的工具来解决验证码问题。例如,最常用的插件是Playwright 库与2Capthca[@extra/recaptcha](https://www.npmjs.com/package/@extra/recaptcha)
结合。
这个 NodeJS 库提供了一种page.solveRecaptchas()
自动解决 reCAPTCHAs 和 hCaptchas 的方法。当还不够时,2Captha 的工作人员将手动解决验证码。
现在,让我们开始工作吧!
步骤#1:首先导航到工作目录并安装@extra/recaptcha
.
npm i @extra/recaptcha
步骤#2:从 2Captcha 获取访问令牌(API 密钥)。
步骤#3:在目录中创建一个名为“ bypassCaptcha.js
”的新文件。在这里,您将编写一个脚本来绕过验证码,包括我们的令牌并<https://www.google.com/recaptcha/api2/demo>
作为目标。
// Import playwright-extra library const { chromium } = require("playwright-extra"); // Import the Recaptcha plugin from playwright-extra library const RecaptchaPlugin = require("@extra/recaptcha"); // Define an asynchronous function to bypass the reCAPTCHA async function bypassRecaptcha() { // Define the options for the reCAPTCHA plugin const RecaptchaOptions = { // Enable visual feedback for the reCAPTCHA visualFeedback: true, // Provide the ID and token for the reCAPTCHA provider provider: { id: "2captcha", token: "XXXXXXX", }, }; // Use the RecaptchaPlugin with the options defined above chromium.use(RecaptchaPlugin(RecaptchaOptions)); // Launch a headless instance of Chromium browser chromium.launch({ headless: true }).then(async (browser) => { // Create a new page in the browser const page = await browser.newPage(); // Navigate to the reCAPTCHA demo page await page.goto("https://www.google.com/recaptcha/api2/demo"); // Solve the reCAPTCHA on the page await page.solveRecaptchas(); // Wait for navigation and click the demo submit button await Promise.all([ page.waitForNavigation(), page.click(`#recaptcha-demo-submit`), ]); // Take a screenshot of the page await page.screenshot({ path: "response.png", fullPage: true }); // Close the browser instance await browser.close(); }); } // Call the `bypassRecaptcha` function bypassRecaptcha();
这是我们的结果
是的,您已成功访问受验证码保护的页面!
注意:涉及验证码时有两种主要方法:1)像我们一样解决它们,2)避免它们,在请求失败时重试。第二种方式通常是专业抓取者的首选,因为它更可靠并且可以节省大量资金。ZenRows就是为您执行后者的工具的一个示例。
方法 5:添加 Playwright-extra
Playwright-extra
是 Playwright 的一个轻量级插件框架,可以启用其他有用的附加组件。我们将用于绕过 Cloudflare 的方法称为Puppeteer-extra-plugin-stealth
,它使用多种技术来隐藏无头浏览器的使用:更改用户代理、生成鼠标事件以及其他反机器人措施。
让我们看看插件的实际效果。但在此之前:
你还记得我们曾试图从基础Playwright那里争取<https://nowsecure.nl>
但失败了吗?让我们再试一次,但https://www.g2.com/
这次要增加一些多样性。
同样,我们到达了著名的Access denied
屏幕。
接下来,我们将使用Puppeteer-extra-plugin-stealth
以避免被阻止:
步骤#1:在您的工作目录中安装 Playwright-extra 和 Puppeteer-extra-stealth。
npm i playwright-extra puppeteer-extra-plugin-stealth
步骤#2:编写脚本来访问主页并拍摄主页快照。
// playwright-extra is a drop-in replacement for playwright, // it augments the installed playwright with plugin functionality const { chromium } = require("playwright-extra"); // Load the stealth plugin and use defaults (all tricks to hide playwright usage) // Note: playwright-extra is compatible with most puppeteer-extra plugins const stealth = require("puppeteer-extra-plugin-stealth")(); // Add the plugin to Playwright (any number of plugins can be added) chromium.use(stealth); // That's it. The rest is Playwright usage as normal 😊 chromium.launch({ headless: true }).then(async (browser) => { const page = await browser.newPage(); console.log("Testing the stealth plugin.."); await page.goto("https://g2.com", { waitUntil: "networkidle" }); await page.screenshot({ path: "g2 passed.png", fullPage: true }); console.log("All done, check the screenshot. ✨"); await browser.close(); });
运行它,并享受:
不幸的是,并非所有页面都具有相同的安全级别,即使共享相同的域也是如此。例如,产品和评论页面通常比主页更难访问。
我们怎么知道这一点?您可以通过测试上面的脚本但将其指向产品评论页面来亲自看到这一点。
我们又被堵住了。我们不要惊慌;我们即将看到一个解决方案来结束我们的噩梦。
Playwright的局限性
Playwright 作为浏览器自动化工具具有强大的优势,但在绕过 Cloudflare 的反机器人措施时也存在多种限制。
正如我们所看到的,补充措施(代理、用户代理等)在一定程度上有所帮助,但当 Cloudflare 采用更先进的机器人检测技术时,您在网络抓取时仍然可能会被阻止。此外,随着反机器人措施的不断发展,今天有效的方法明天可能就行不通了。
因此,为了确保更可靠的抓取过程并获取您想要的数据,建议使用像ZenRows这样的网络抓取工具,它提供了许多避免检测的功能。ZenRows简化了数据抓取过程,并通过单个 API 调用为您提供任何网页的内容。
我们将以 G2 的产品评论页面为例向您展示差异。
步骤#1:在几秒钟内 创建一个免费帐户。
步骤 #2:在请求生成器页面上,输入https://www.g2.com/products/asana/reviews
目标 URL 并选择 Node.js 作为语言。然后,激活Premium Proxy
、J
avaScript Rendering
并Antibot
克服反机器人保护。另外,我们添加了 CSS 选择器来获取页面标题和评论数量。
我们只需先单击该Try it
按钮即可查看它是否有效,但您可以复制自动生成的 Node.js 脚本并在代码库中使用它。
输出如下。
{ "stats": [ "9,183 reviews", "129 discussions" ], "title": "Asana Reviews & Product Details" }
结论
正如您所看到的,可以使用 Playwright 绕过 Cloudflare,但您可能需要应用一些高级技术,这不一定能完成工作。