一、UA 的结构
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
大致分四段:
Mozilla/5.0:历史遗留,几乎所有浏览器都带,用来兼容老站点。- 括号内:平台信息(系统、架构、设备)。
AppleWebKit/537.36 (KHTML, like Gecko):渲染引擎标识。- 末尾:浏览器名与版本。
看起来信息很多,但每一段都可以被伪造,而且历史原因导致大量「不准确」:Chrome 自称 Safari、Edge 自称 Chrome、Safari 也带 like Gecko。所以解析 UA 必须用成熟的解析库,而不是自己写正则。
二、常见标识
| 类型 | 关键片段 |
|---|---|
| Chrome | Chrome/xxx(且不含 Edg/) |
| Edge | Edg/xxx |
| Safari | Safari/xxx(且不含 Chrome/) |
| Firefox | Firefox/xxx |
| 微信内置 | MicroMessenger/xxx |
| 支付宝 | AlipayClient/xxx |
| 百度蜘蛛 | Baiduspider |
| Google 蜘蛛 | Googlebot |
| 字节蜘蛛 | Bytespider |
| curl / 脚本 | curl/xxx、python-requests/xxx、Go-http-client/xxx |
判断「是不是 Chrome」的正确逻辑是「包含 Chrome/ 且不包含 Edg/、OPR/」——因为 Edge 和 Opera 的 UA 里也有 Chrome/。
三、靠 UA 判断移动端不可靠
常见写法:
const isMobile = /Mobile|Android|iPhone/.test(navigator.userAgent);
问题:
- iPad 的 UA 现在默认是桌面版 Safari。
- 安卓平板可能不带
Mobile。 - 用户可以随意改 UA。
- 折叠屏、二合一设备两种形态切换。
判断设备能力应该用特性检测(matchMedia、pointer: coarse、navigator.maxTouchPoints),判断布局用 CSS 媒体查询。UA 只适合做「统计」和「兜底跳转」。
四、UA 缩减与 Client Hints
Chrome 从 101 起推行 UA 缩减:UA 里的版本号被冻结成 Chrome/110.0.0.0 这种固定值,详细信息系统移到 User-Agent Client Hints(Sec-CH-UA、Sec-CH-UA-Platform 等请求头),需要服务端通过 Accept-CH 主动索取。
影响:
- 靠 UA 做「浏览器版本判断」的代码会失效(版本号不再精确)。
- 需要版本信息时改用 Client Hints 或特性检测。
- 指纹类方案受影响,隐私保护是目的。
五、识别爬虫的正确姿势
UA 里的 Baiduspider 谁都能写。要验证真实性:
- 反向 DNS:蜘蛛 IP 反解到官方域名(如
baiduspider-*.crawl.baidu.com)。 - 正向解析:再解析回来确认是同一个 IP。
- 或用官方公布的 IP 段。
只靠 UA 判断爬虫,会同时犯两个错:放过伪装者、误杀改了 UA 的正常用户。
六、按 UA 分流的注意事项
如果一定要根据 UA 返回不同内容(如给微信用户展示「用浏览器打开」提示),注意:
- 不要让内容差异影响 SEO:搜索引擎看到的内容应与用户一致,否则可能被判为「伪装」。
- 提供「跳过」入口,别把用户困在提示页。
- 记录 UA 便于排查,但别把它当唯一依据。
七、日志里的 UA 有什么用
- 统计各浏览器/系统占比,决定兼容性投入。
- 发现异常流量:大量
python-requests、空 UA、异常版本的集中请求。 - 排查兼容问题:用户反馈「页面错乱」时,先看他用的浏览器版本。
用 User-Agent 解析工具 可以把一长串 UA 拆成浏览器、版本、系统、设备类型,比自己看字符串快。
小结
UA 是自报字符串、可伪造、历史包袱重;浏览器判断要排除 Edge/Opera;移动端判断用特性检测;爬虫要验证 IP 反解;UA 缩减后用 Client Hints。