本文详细介绍浏览器useragent指纹是什么,监测站怎么检测的,并提供3钟修改浏览器ua的方法。通过修改浏览器启动参数–user-agent,通过自动化框架playwright和puppetteer之类的修改浏览器useragent指纹和通过修改chromium源码定制修改开源指纹浏览器的userAgent指纹信息。
本专题系列教程源码将放在 github 上开源指纹浏览器供大家学习,大家可以关注我,或者star github项目来收到更新通知。
浏览器 User-Agent 介绍
User-Agent(用户代理)是浏览器或其他客户端应用程序在HTTP请求头中发送的一个字符串,用于向服务器标识自己的身份。它包含了关于浏览器类型、版本、操作系统以及渲染引擎等信息。
User-Agent 的结构
典型的 User-Agent 字符串格式如下:
Mozilla/[version] ([system and browser information]) [platform] ([platform details]) [extensions]
示例(Chrome 在 Windows 上的 User-Agent):
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
User-Agent 的组成部分
- Mozilla/5.0 - 历史遗留部分,几乎所有现代浏览器都包含
- 平台信息 - 如
(Windows NT 10.0; Win64; x64)
- 渲染引擎 - 如
AppleWebKit/537.36
- 兼容性信息 -
(KHTML, like Gecko)
- 浏览器信息 - 如
Chrome/91.0.4472.124
- 其他兼容性信息 - 如
Safari/537.36
常见浏览器的 User-Agent 示例
Google Chrome
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36
Mozilla Firefox
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Microsoft Edge
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.59
Safari (Mac)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15
Mobile Safari (iPhone)
Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1
User-Agent 的用途
- 内容适配 - 服务器根据UA返回适合的内容(如移动版或桌面版)
- 浏览器统计 - 分析用户使用的浏览器和操作系统分布
- 功能检测 - 某些网站根据UA决定是否启用特定功能
- 爬虫识别 - 识别网络爬虫和机器人
关于User-Agent的一些新动态
- User-Agent 可以被伪造,不能完全依赖它进行安全验证
- User-Agent 嗅探(根据UA限制功能)被认为是不良实践,应使用特性检测代替
- 随着隐私保护加强,一些浏览器开始限制UA信息的详细程度(如苹果的Safari)
为什么会有两个UserAgent?
当你使用检测网站检测浏览器的UserAgent指纹的时候,你会发现有2个UserAgent,这是为什么呢?
在JavaScript中,可以通过navigator.userAgent
属性获取当前浏览器的User-Agent字符串,浏览器在发送网络请求的时候也会携带userAgent.如果修改不到位,可能导致其不匹配。
修改Chromium UserAgent的几种方法
第一种方式 启动浏览器添加命令行
格式 --user-agent=“自定义的UA”
例子
chrome.exe --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"
这种方式是最推荐的,简单可靠,无需涉及修改源码,不会导致不一致的值
方法二 使用自动化脚本(例如Playwright) 设置 User-Agent
这也是推荐的方式,自动化框架使用的是成熟的接口,简单,稳定,可靠,下面是playwright 设置user-agent的代码
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
});
const page = await context.newPage();
await page.goto('https://example.com');
// 验证 User-Agent
const userAgent = await page.evaluate(() => navigator.userAgent);
console.log(userAgent);
await browser.close();
})();
方法三 修改chromium源码 设置useragent值
chromium源码中user agent的位置在components\embedder_support\user_agent_utils.cc和content\common\user_agent.cc中。不是很推荐这种方式,原因是复杂,要改chromium源码,还可能引入奔溃,bug和不一致。
修改components\embedder_support\user_agent_utils.cc,找到下面代码和函数,把user agent改成自己想 要的样子便可。
std::string GetUserAgentInternal(
UserAgentReductionEnterprisePolicyState user_agent_reduction) {
std::string product = GetProductAndVersion(user_agent_reduction);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(kHeadless)) {
product.insert(0, "Headless");
}
#if BUILDFLAG(IS_ANDROID)
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kUseMobileUserAgent))
product += " Mobile";
#endif
return ShouldSendUserAgentUnifiedPlatform(user_agent_reduction)
? content::BuildUnifiedPlatformUserAgentFromProduct(product)
: content::BuildUserAgentFromProduct(product);
}
absl::optional<std::string> GetUserAgentFromCommandLine() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(kUserAgent)) {
std::string ua = command_line->GetSwitchValueASCII(kUserAgent);
if (net::HttpUtil::IsValidHeaderValue(ua)) {
return ua;
}
LOG(WARNING) << "Ignored invalid value for flag --" << kUserAgent;
}
return absl::nullopt;
}
std::string GetUserAgent(
UserAgentReductionEnterprisePolicyState user_agent_reduction) {
absl::optional<std::string> custom_ua = GetUserAgentFromCommandLine();
if (custom_ua.has_value()) {
return custom_ua.value();
}
return GetUserAgentInternal(user_agent_reduction);
修改 content\common\user_agent.cc,找到下面函数,针对修改里面的内容便可
std::string BuildUserAgentFromProduct(const std::string& product) {
std::string os_info;
base::StringAppendF(&os_info, "%s%s", GetUserAgentPlatform().c_str(),
BuildOSCpuInfo(IncludeAndroidBuildNumber::Exclude,
IncludeAndroidModel::Include)
.c_str());
return BuildUserAgentFromOSAndProduct(os_info, product);
}
std::string BuildUserAgentFromOSAndProduct(const std::string& os_info,
const std::string& product) {
std::string user_agent;
base::StringAppendF(&user_agent,
"Mozilla/5.0 (%s) AppleWebKit/537.36 (KHTML, like Gecko) "
"%s Safari/537.36",
os_info.c_str(), product.c_str());
return user_agent;
}