如何通过Playwright避免机器人检测
Playwright 是一款功能强大的无头浏览器,需要几行代码即可实现快速浏览器自动化。它的简单性和广泛的功能使其在网络抓取工具中很受欢迎,但在网络抓取时很容易被阻止。
在本教程中,我们将讨论是什么使Playwright scraper可检测到以及如何避免 Playwright 机器人检测。
Playwright可以被检测到吗?
是的,具有反机器人措施的网站可以轻松检测到 Playwright,因为它表现出自动浏览器特有的行为。
此外,它还显示命令行标志和固有属性,例如navigator.webdriver
,尖叫“我是机器人”。默认情况下启用它们是为了改善自动化体验,但对网络抓取工具来说却是有害的。
然而,好消息是您可以通过屏蔽您的请求并模仿人类行为来避免Playwright检测。让我们看看如何。
避免 Playwright 检测到机器人的最佳措施
在我们讨论确保您的 Playwright scraper 顺利运行的最佳措施之前,您需要勾选以下所有框:
先决条件
以下是您需要遵循本教程的内容:
- 确保您已安装Node.js。
- 使用以下命令安装 Playwright。
npm install playwright
- 添加
"type" : "module"
到您的package.json
文件中以启用现代 JavaScript 语法(默认为 TypeScript)。您的文件应如下所示:
Playwright 的安装附带浏览器二进制文件,因此可能需要一些时间。
现在您的环境已准备就绪,让我们看看如何避免 Playwright 机器人检测。
1. 使用代理
代理充当网络抓取工具和目标网站之间的中介。它会拦截并发送来自不同 IP 地址的请求,以增加您的匿名性。然而,代理的类型很重要。让我们比较一下住宅和数据中心,因为它们最受欢迎。
住宅代理是指属于真实用户设备且不太可能被检测为机器人的 IP 地址。另一方面,数据中心代理的 IP 地址托管在数据中心上,很容易被检测到。正如您所猜测的,大多数高级代理都是住宅代理,而免费代理通常托管在数据中心。
此外,网站通常会将来自单个 IP 地址的过多请求识别为机器人行为并限制请求。要绕过速率限制,您需要根据请求轮换代理。这样,您就可以跨多个 IP 分配抓取流量,以使请求显得更加自然。
也就是说,使用 Playwright 通过代理路由您的请求很容易。您所需要做的就是将代理凭据作为启动选项传递。
免费代理仅用于测试,因为它们不可靠。因此,您应该考虑使用高级代理进行网络抓取以获得最佳结果,他们会为您自动轮换住宅 IP。
2. 随机化用户代理
每个 HTTP 请求都包含 HTTP 标头,这些标头提供有关请求和发出请求的客户端的附加上下文和元数据。特别是,用户代理标头在网络抓取中非常重要,如果您的请求包含Playwright的默认 UA,网站可以轻松检测并阻止或限制您的访问。
真正的 UA 是这样的:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
然后,虽然在某些情况下简单地将用户代理字符串更改为实际浏览器的字符串可能会起作用,但这很少是足够的。当面对复杂的反机器人措施(例如请求模式或频率分析)时,您最终会被发现。
因此,随机化您的 UA 和其他标头将使您的请求更加自然,从而使网站更难检测到您的抓取工具。以下是如何使用 Playwright 随机化用户代理:
首先,在数组中定义用户代理字符串列表。
const userAgentStrings = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.2227.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.3497.92 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', ];
确保您的 UA 与其他标头和您正在模拟的浏览器兼容。例如,如果您的用户代理是 Windows 上的 Google Chrome v83,而其他标头是 Mac 的标头,则您的目标网站可能会检测到这种差异并阻止您的请求。查看我们有关如何设置新用户代理的指南以了解更多信息。
接下来,启动 Chromium 浏览器实例并使用随机选择的用户代理创建新上下文。
// Create a new page in the browser context and navigate to target URL const page = await context.newPage(); await page.goto('http://httpbin.org/headers');
把它们放在一起,我们有以下代码:
import { chromium } from 'playwright'; // An array of user agent strings for different versions of Chrome on Windows and Mac const userAgentStrings = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.2227.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.2228.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.3497.92 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', ]; (async () => { // Launch the Chromium browser const browser = await chromium.launch(); // Create a new browser context with a randomly selected user agent string const context = await browser.newContext({ userAgent: userAgentStrings[Math.floor(Math.random() * userAgentStrings.length)], }); // Create a new page in the browser context and navigate to target URL const page = await context.newPage(); await page.goto('https://httpbin.org/headers'); })();
验证其是否有效并关闭浏览器。
console.log(await page.textContent("*")); // Close the browser when done await browser.close();
您将得到以下结果:
{ "headers": { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Encoding": "gzip, deflate, br", "Host": "httpbin.org", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", "X-Amzn-Trace-Id": "Root=1-64238f2a-0f818f50596439c7688bfba6" } }
如果每次运行此代码时获得不同的用户代理字符串,则说明您已成功。
您还可以使用for
循环发出多个请求,完整的代码应如下所示:
import { chromium } from 'playwright'; const userAgentStrings = [ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.2227.0 Safari/537.36', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.2228.0 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.3497.92 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36', ]; (async () => { const browser = await chromium.launch(); for (const userAgent of userAgentStrings) { const context = await browser.newContext({ userAgent }); const page = await context.newPage(); await page.goto('https://httpbin.org/headers'); console.log(await page.textContent('*')); await context.close(); } await browser.close(); })();
3.绕过验证码
验证码是旨在防止机器人获取网站数据或与网站数据交互的安全措施。这些挑战主要是由类似机器人的行为引发的,例如异常的流量峰值、可疑的请求模式等。
绕过验证码的主要方法有两种:完全避免它们或在它们出现时解决它们。第一个是最好的路径,因为它可以节省时间,并且更可靠、可扩展且更便宜。
避免验证码的关键是模仿人类行为并规避其触发因素。凭借自动化人类浏览器操作的能力,Playwright 提供了实现这一目标的方法。查看我们关于最佳验证码代理的指南以了解更多信息。
4. 禁用自动化指示器 WebDriver 标志
如前所述,Playwright 的属性将其标记为自动浏览器。反机器人检测措施可以轻松识别这些属性,并通知 Web 服务器机器人控制了浏览器。这些属性之一是.webdriver
.
自动化工具必须具有诸如navigator.webdriver
促进与其他 Web 应用程序的兼容性以及提供更好的自动化功能和安全性等属性。然而,这些功能对于旨在避免机器人检测的网络抓取工具来说是有问题的。
幸运的是,Playwright 提供了一种禁用webdriver
标志并增加避免检测的机会的方法。通过其内置addInitScript()
功能,您可以将navigator.webdriver
属性设置为undefined
。
在脚本中添加以下代码init
来执行此操作。
Object.defineProperty(navigator, 'webdriver', { get: () => undefined, });
然后,将其添加到我们原来的 Playwright 网络抓取工具中。
//import playwright import { chromium } from 'playwright'; (async () => { //launch Chromium browser instance const browser = await chromium.launch(); //create new context const context = await browser.newContext(); //add init script await context.addInitScript("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") //open new page using context const page = await context.newPage(); //navigate to target website await page.goto('https://www.example.com'); // wait for the page to load await page.waitForTimeout(10000); //take a screenshot and save to a file await page.screenshot({ path: 'example.png' }); // Turn off the browser. await browser.close(); })();
5. 使用 Cookie
Cookie 是网站发送给客户端的小数据包,用于跟踪用户活动。接收并存储它们后,它们会随每个请求发送回 Web 服务器。这样,网站就可以维护不同会话之间的会话状态。
由于避免检测是为了模拟真实的用户行为,因此您可以在请求中包含 cookie,使其看起来像重新访问的用户。Web 服务器希望如此,如果操作正确,您可以在雷达下飞行以检索必要的数据。
您可以使用该context.addCookies()
方法在 Playwright 的上下文中设置 cookie,以使它们在该上下文中全局可用。此外,您还可以使用该page.SetCookie()
方法为特定页面设置它们。
6.找一个Playwright
另一种避免检测的方法是使用 playwright-extra 来强化 Playwright,这是一个支持附加插件的流行库。有了它,您可以扩展网络抓取工具的功能,以完成需要更灵活地定制请求的任务。
您有多个附加组件,但隐形插件是最重要的一个。它的目的是通过修改发送到网络服务器的信息来防止网站检测到浏览器是自动的。
要将其与 Playwright 一起使用,请安装 playwright-extra 和 puppeteer-extra-plugin-stealth,加载 Stealth 插件并照常使用 Playwright。
然而,虽然这可以帮助您避免检测,但您需要采取不同的方法来应对更先进的反机器人措施。
这就引出了一个问题,最终的解决方案是什么?让我们来看看!
使用 ZenRows 屏蔽请求
反机器人解决方案正在不断快速发展,因此无论使用何种技术来避免 Playwright 机器人检测,您仍然可能会被阻止。
幸运的是,ZenRows 经过专门设计,可以避免最复杂的反机器人措施,并且拥有您为此目的可能需要的一切:高级轮换代理、轮换用户代理、JavaScript 渲染等等。您可以通过单个 API 调用轻松检索所需的网站数据。
下面,请参阅 ZenRows 针对G2 评论页面(一个使用高级反机器人保护的网站)的操作。
要按照本教程进行操作,请注册以获取免费的 API 密钥。注册后您会在页面顶部找到它。
然后,安装axios。
npm install axios
您只需导入 Axios 并使用必要的参数调用 ZenRows API 即可访问您的目标 URL。为了避免检测,请设置antibot=true
和premium_proxy=true
(您可能还需要设置js_render=true
)。因此,您的完整代码应如下所示:
//import axios const axios = require("axios"); // Call ZenRows API with the provided url and parameters axios({ url: "https://api.zenrows.com/v1/?apikey=YOUR_API_KEY&url=https%3A%2F%2Fwww.g2.com%2Fproducts%2Fg2%2Freviews&antibot=true&premium_proxy=true", method: "GET", }) .then(response => console.log(response.data)) .catch(error => console.log(error));
恭喜,您已绕过高级反机器人检测!
结论
避免 Playwright 机器人检测可能是一项艰巨的任务,因为它的属性和命令行标志使网站可以轻松检测和阻止它。此外,反机器人措施正在快速发展,因此任何掩盖自动化属性的技术可能仍然不够。