Puppeteer User Agent 指南:设置和更改

掌握在 Puppeteer 中设置和轮换 User Agent 的技巧,以提升您的网页抓取效果并绕过反机器人防御。
4 min read
Puppeteer
User Agent 指南

在这篇 Puppeteer User Agent 指南中,您将会看到:

  • 为什么在 网页抓取 中设置 User-Agent 头至关重要
  • Puppeteer 中默认的 User Agent 是什么样的
  • 如何覆盖默认的 Chrome 无头浏览器 User Agent
  • 如何在 Puppeteer 中实现 User Agent 轮换
  • 如何使用 Puppeteer Extra 来匿名化 User Agent

让我们开始吧!

为什么需要设置自定义 User Agent

User-Agent 头是客户端在通过 HTTP 请求联系服务器时用于标识自身的字符串。它通常包括关于请求来源的机器和/或应用程序的信息。这个头由网页浏览器、HTTP 客户端或任何执行网页请求的软件设置。

下面是 Chrome 在请求网页时设置的 User Agent 字符串示例:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36

上述 User Agent 字符串由以下组件组成:

  • Mozilla/5.0:最初用于表示与 Mozilla 浏览器的兼容性,现在这个前缀被包含在内以实现更广泛的兼容性。
  • Windows NT 10.0; Win64; x64:指示操作系统(Windows NT 10.0)、平台(Win64)和系统架构(x64)。
  • AppleWebKit/537.36:指的是 Chrome 使用的浏览器引擎。
  • (KHTML, like Gecko):表示与 KHTML 和 Gecko 排版引擎的兼容性。
  • Chrome/127.0.0.0:指定浏览器名称和版本。
  • Safari/537.36:表示与 Safari 的兼容性。

基本上,User Agent 字符串可以揭示请求是来自知名浏览器还是其他类型的软件。

大多数 网页抓取机器人 和自动化脚本最常见的错误是使用默认的或非浏览器的 User Agent。这些值很容易被用于保护网页的反机器人措施检测到。通过分析 User-Agent 头,服务器可以确定请求是否可能来自自动化的机器人。

欲了解更多详细信息,请查看我们的 网页抓取的 User Agent 指南

默认的 Puppeteer User Agent 是什么?

Puppeteer 通过控制一个特殊版本的真实网页浏览器来自动化浏览器任务。默认情况下,它运行特定版本的 Chrome,尽管它也支持 Firefox。因此,您可能认为 Puppeteer 中的默认 User Agent 将与所控制的 Chrome 版本设置的 User Agent 匹配。然而,事实并非如此……

原因是 Puppeteer 默认以无头模式启动浏览器。当浏览器在无头模式下运行时,它们通常会设置一个独特的 User Agent。截至当前版本,默认的 Puppeteer User Agent 如下所示:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/127.0.0.0 Safari/537.3

请注意 HeadlessChrome 字符串,它表明 Chrome 正在无头模式下运行。不意外的是,上述字符串正是最新版本的无头 Chrome 的 User Agent。

为了确认上述字符串确实是 Puppeteer 的默认 User Agent,设置一个脚本并导航到 httpbin.io/user-agent 页面。这个 API 端点返回请求的 User-Agent 头,帮助您发现任何浏览器或 HTTP 客户端使用的 User Agent。

创建一个 Puppeteer 脚本,访问目标页面,从主体中获取 API 响应,并打印出来:

import puppeteer from "puppeteer";

(async () => {

// launch the browser and open a new page

const browser = await puppeteer.launch();

const page = await browser.newPage();

// connect to the target page

await page.goto("https://httpbin.io/user-agent");

// extract the body text with the API response

// and print it

const bodyText = await page.evaluate(() => {

return document.body.innerText;

});

console.log(bodyText);

// close the browser and release its resources

await browser.close();

})();

要了解更多关于 Puppeteer API 的信息,请阅读我们的 使用 Puppeteer 进行网页抓取的指南

运行上述 Node.js 代码,您将收到以下字符串:

{

"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/127.0.0.0 Safari/537.36"

}

请注意,Puppeteer 设置的 User Agent 与之前呈现的字符串相匹配。

问题在于 HeadlessChrome 标识符,它可能会引起 反机器人系统 的警觉。这些系统通过分析传入请求的模式(例如不寻常的 User Agent 字符串)来检测可能指示机器人活动的请求。可疑的请求会被标记并相应地阻止。这就是为什么修改默认的 Puppeteer User Agent 字符串如此重要!

如何更改 Puppeteer User Agent

更改 User Agent 是如此常见且有用的操作,以至于 Puppeteer 专门提供了一个方法。特别是,Page 类公开了 setUserAgent() 方法。这允许您在该浏览器选项卡中导航到网页时修改 Puppeteer 设置的 User-Agent

使用 setUserAgent() 来更改 Puppeteer 的 User Agent,如下所示:

await page.setUserAgent("<your_user_agent>");

现在,通过在 page 上调用 goto() 方法进行的所有 HTTP GET 请求都将具有自定义的 User-Agent 头。请记住,此更改仅适用于特定的 page 对象。如果您打开一个新页面并与之交互,Puppeteer 将使用之前看到的默认 User Agent。

完整的示例如下所示:

import puppeteer from "puppeteer";

(async () => {

// launch the browser and open a new page

const browser = await puppeteer.launch();

const page = await browser.newPage();

// set a custom user agent

await page.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36");

// connect to the target page

await page.goto("https://httpbin.io/user-agent");

// extract the body text with the API response

// and print it

const bodyText = await page.evaluate(() => {

return document.body.innerText;

});

console.log(bodyText);

// close the browser and release its resources

await browser.close();

})();

执行上述脚本,这次结果将是:

{

"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"

}

太棒了!从页面提取的 User Agent 字符串与代码中配置的 User Agent 相匹配。您现在知道如何执行 Puppeteer 更改 User Agent 的操作。

在 Puppeteer 中实现 User Agent 轮换

将无头浏览器的 User-Agent 头替换为非无头浏览器的 User Agent 可能不足以避免 反机器人系统。问题在于您的浏览器自动化脚本将表现出非人类行为的模式。如果您使用相同的头和相同的 IP 地址发送大量请求,情况尤其如此。

为了最大限度地降低在 Puppeteer 中被机器人检测到的风险,您需要使请求尽可能多样化。一个有效的方法是为每个请求设置不同的 User Agent。这种策略称为 User Agent 轮换,有助于降低被标记为机器人的可能性。

在接下来的教程部分,您将学习如何在 Puppeteer 中实现 User Agent 轮换!

步骤一:生成随机的 User Agent

获取随机 User Agent 有两种主要方法。第一种是获取有效 User Agent 的列表,并从列表中随机选择一个,正如我们在 Node.js User Agent 指南中所示。

第二种方法是使用第三方 User Agent 生成器库。JavaScript 中最流行的是 user-agents,这是一个可以为您生成有效 User Agent 的包。在本指南中,我们将遵循这种方法!

运行此 npm 命令将 user-agents 库添加到项目的依赖项中:

npm install user-agents

请注意,user-agents 每日更新,确保它始终包含最新的 User Agent。

安装库后,将 UserAgent 对象导入您的 Puppeteer 脚本:

import UserAgent from "user-agents";

现在,您可以使用以下代码生成一个随机的 User Agent 字符串:

const userAgent = new UserAgent().random().toString();

查看官方文档,了解更高级的用法,例如获取特定设备、操作系统的 User Agent 等。

步骤二:设置随机 User Agent

通过调用 PuppeteersetUserAgent() 方法,将随机的 User Agent 字符串传递给 Puppeteer

const userAgent = new UserAgent().random().toString();

await page.setUserAgent(userAgent);

现在,通过 page 对象执行的所有请求都将具有随机生成的自定义 User Agent。

步骤三:访问目标页面

page 上调用 goto() 方法,在受控的无头浏览器中访问目标网页:

await page.goto("https://httpbin.io/user-agent");

步骤四:整合所有步骤

以下是您的最终 Puppeteer User Agent 轮换脚本:

import puppeteer from "puppeteer";

import UserAgent from "user-agents";

(async () => {

// launch the browser and open a new page

const browser = await puppeteer.launch();

const page = await browser.newPage();

// generate a random user agent

const userAgent = new UserAgent().random().toString();

// set a random user agent

await page.setUserAgent(userAgent);

// connect to the target page

await page.goto("https://httpbin.io/user-agent");

// extract the body text with the API response

// and print it

const bodyText = await page.evaluate(() => {

return document.body.innerText;

});

console.log(bodyText);

// close the browser and release its resources

await browser.close();

})();

运行脚本几次,您应该会看到不同的 User Agent。

就是这样!在 Puppeteer 中的 User Agent 轮换逻辑运作良好。

使用 puppeteer-extra-plugin-anonymize-ua 在 Puppeteer 中设置自定义 User Agent

上述更改 Puppeteer User Agent 的方法是有效的,但它们有一个显著的缺点。userAgent() 方法只更改特定页面会话的 User Agent,而不是跨所有浏览器选项卡。

为了确保 Puppeteer 永远不使用默认的 User Agent,您可以使用 puppeteer-extra-plugin-anonymize-ua 插件,该插件来自 Puppeteer Extra。如果您不熟悉该项目,Puppeteer Extra 通过添加对社区定义的插件的支持来扩展 Puppeteer。您可以在我们的 Puppeteer Extra Stealth 插件指南中了解更多。

puppeteer-extra-plugin-anonymize-ua 插件可以匿名化 Puppeteer 设置的 User Agent。要安装 puppeteer-extra 和必要的插件,请运行以下命令:

npm install puppeteer-extra puppeteer-extra-plugin-anonymize-ua

接下来,从 puppeteer-extra 导入 puppeteer,并从 puppeteer-extra-plugin-anonymize-ua 导入 AnonymizeUAPlugin

import puppeteer from "puppeteer-extra";

import AnonymizeUAPlugin from "puppeteer-extra-plugin-anonymize-ua";

配置 puppeteer-extra-plugin-anonymize-ua 以生成随机的 User Agent,并使用 Puppeteer Extrause() 方法将其注册为插件:

puppeteer.use(

AnonymizeUAPlugin({

customFn: () => new UserAgent().random().toString(),

})

);

现在,尝试使用两个不同的 page 对象在两个不同的选项卡中访问页面:

import puppeteer from "puppeteer-extra";

import AnonymizeUAPlugin from "puppeteer-extra-plugin-anonymize-ua";

import UserAgent from "user-agents";

(async () => {

// configure and register the

// puppeteer-extra-plugin-anonymize-ua plugin

puppeteer.use(

AnonymizeUAPlugin({

customFn: () => new UserAgent().random().toString(),

})

);

// launch the browser and open a new page

const browser = await puppeteer.launch();

// open a new page

const page1 = await browser.newPage();

// connect to the target page

await page1.goto("https://httpbin.io/user-agent");

// extract the body text with the API response

// and print it

const bodyText1 = await page1.evaluate(() => {

return document.body.innerText;

});

console.log(bodyText1);

// open a new page

const page2 = await browser.newPage();

// connect to the target page

await page2.goto("https://httpbin.io/user-agent");

// extract the body text with the API response

// and print it

const bodyText2 = await page2.evaluate(() => {

return document.body.innerText;

});

console.log(bodyText2);

// close the browser and release its resources

await browser.close();

})();

结果将是两个不同的 User Agent,如下所示:

{

"user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1"

}

{

"user-agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Mobile Safari/537.36"

}

这两个 User Agent 是不同的,且都不是默认的 Puppeteer User Agent。这是因为 puppeteer-extra-plugin-anonymize-ua 使用在 customFn 函数中指定的随机 User Agent 来定制每个 page 对象。这样,Puppeteer 将永远不会暴露其默认的 User Agent!

结论

在本文中,您探讨了设置 User-Agent 头的重要性,并看到了默认的 Puppeteer User Agent 是什么样子的。您学习了如何覆盖该值并实现 User Agent 轮换以避免基本的反抓取系统。然而,更复杂的系统仍然可以检测并阻止您的自动化请求。为了防止 IP 被封禁,您可以在 Puppeteer 中配置代理,但即使这样也可能不够!

为了获得更有效的解决方案,试试 Scraping Browser —— 一个与 Puppeteer 和任何其他浏览器自动化工具集成的下一代浏览器。Scraping Browser 可以轻松地为您绕过反机器人技术,同时避免浏览器指纹识别。在幕后,它依赖于 User Agent 轮换、IP 轮换CAPTCHA 解决 等功能。浏览器自动化从未如此简单!

立即注册并开始您的免费试用。