杂记 › 技术笔记 › 服务器日志里那串 User-Agent,哪几个字段是自己填的

服务器日志里那串 User-Agent,哪几个字段是自己填的

引号之间那一段,是客户端自己写的

有次翻 Nginx 的 access.log,想确认反复来取接口的到底是谁:搜索引擎的蜘蛛、微信内置浏览器里的真人,还是拿脚本把自己写成 Chrome 的人。证据只有引号之间那段 User-Agent,而它是客户端自己拼出来、原样发上来的——「像 Chrome」和「是 Chrome」是两个命题:前者查字面,后者要字面以外的东西。

先摆尺度:8 条样本最长 274 字符、最短 curl/8.5.0 的 10 字符,合计 935。段落数量与顺序全由发出去那一端决定。

Chrome / Win 111 字符 Edge / Win 125 字符 Safari / Mac 117 字符 Firefox / Win 80 字符 iPhone Safari 135 字符 安卓微信 274 字符 百度蜘蛛 83 字符 curl 命令行 10 字符

图 1|8 条样本的字符数,条形按字符数等比。

六个维度各读哪一段,值从哪张表来

维度值从哪里来读不到时显示
浏览器 / 客户端BROWSERS 32 条自上而下取首个命中未识别
渲染内核独立一条链:Trident、Edge、Chromium 裸子串、Gecko—(非浏览器 UA)
操作系统Windows NT 映射表 7 条命中—(无法判断)
设备类型iPad、iPhone、是否带 Mobile,再问爬虫—(无法判断)
CPU 架构Intel Mac 优先,arm64 对 x64,WOW64 另判—(未声明)
语言环境8 条里只有安卓微信给出 zh-cn其余 7 条 —(未声明)

安卓微信那条同时有 AppleWebKit/537.36 与 MicroMessenger/8.0.40.2420,客户端给 微信(内置浏览器) 8.0.40.2420,内核却给 Blink(Chromium 内核) / 537.36;Safari/Mac 是 WebKit(Safari 内核) / 605.1.15,两根轴各判各的。

同一条字符串,位次决定它变成谁

  • MicroMessenger 排第 1 条,安卓微信那条里的 Chrome/77.0.3969.139 轮不到。
  • Edg 第 13 条早于旧版 Edge 第 14 条;Chrome 第 28 条、Firefox 第 30 条、Safari 第 31 条。
  • 爬虫表 21 条,兜底那条排在具名蜘蛛与程序库之后。
  • 程序库也走爬虫表:curl/8.5.0 第 13 条、python-requests/2.31.0 第 15 条。
安卓微信 第 1 条 Edge 第 13 条 旧版 Edge 第 14 条 Chrome 第 28 条 Firefox 第 30 条 Safari 第 31 条

图 2|浏览器表 32 条里各类客户端的命中位次,条形按位次等比。

爬虫那侧优先级更高:先跑 detectBot,有返回就不看浏览器表。伪造那条 compatible; Spybot/1.0 夹着合法的 Chrome/131.0.0.0,本可命中第 28 条,卡片却写 自动化程序 / 爬虫、主版本号 bot——命中 21 条里最后的兜底 /(bot|spider|crawler|fetcher|httpclient)\b/i。只写 compatible; GenericClient/1.0 时兜底不响,回落 Chrome 131.0.0.0,操作系统与设备都是 —(无法判断)。

内核栏为什么会自己冒出 Blink

detectEngine 的 Chromium 分支是 /Edg|OPR|Vivaldi|Chrome|CriOS|Chromium/ 裸子串,没有 i 修饰符。小写因此不算:3 条只含 pledge、edgeless、knowledge-sync 的 UA 被它命中的条数是 0,最后那条照报 Gecko 132.0。

大写就中招:4 条含大写子串的自建 UA 被改判的条数正是 4——机型名 OPRO-X、设备名 Chromecast、EdgeSync-Agent/2.0 全报成 Blink(Chromium 内核)且版本为空;一条 Firefox 128.0 只因尾部多了 MicrosoftEdgeRuntime 就从 Gecko 变 Blink,第 5 条真 Edge 对照一致。「内核有名字、版本为空」就是信号。

版本号里那些下划线是谁换掉的

iOS 捕获 17_4 换点后显示 iOS 17.4,macOS 的 10_15_7 显示 10.15.7。Windows 那张映射表只有 7 条命中,10.0 对 Windows 10 / 11 直到 5.2 对 Windows Server 2003,取不到就回落「较老版本」:NT 11.0、6.4、5.0 都算较老版本,真 Windows 11 走的反而是 10.0。微信 8.0.40.2420 的 4 段全保留,(0x28002837) 不参与版本;rv:132.0 优先于 20100101。

第三张表只解释字面,不下结论

TOKENS 34 条只说明每段是什么意思。对 125 字符那条 Edge/Win 做高亮,命中 9 个片段,25 条没匹配上或被区间重叠去掉。两条注释回答开头:Mozilla/5.0「几乎所有浏览器都固定写 5.0,不代表浏览器品牌」,(KHTML, like Gecko) 是「WebKit 的伪装声明」。这 34 条我背不下来,通常把整行丢进User-Agent 解析逐段标出来。

「到底是谁」这一栏答不了。要把蜘蛛和伪装者分开,得拿同一行日志里的 IP 去对归属地与反向解析,IP 归属地查询给的机房线索才回答「这台机器有没有可能是百度出口」。模板里 Sec-CH 与 Client Hints 各出现 0 次,所以冻结在 108.0.0.0 的精简版只能读成 Chrome 108.0.0.0;尾部挂着编码过的一段,先按 Base64 编解码解一遍。

Q:UA 能不能伪造?

能,不需要技巧——那串字符本来就是客户端拼的。有爬虫关键词就落到 自动化程序 / 爬虫,没有就回落 Chrome 131.0.0.0。它读字面不读来源,只靠这一栏做访问控制都能被绕过。

Q:为什么 Chrome 的 UA 里写着 Safari?

兼容遗留。Chromium 系结尾都带一段 Safari/537.36,注释写着「Chromium 结尾也带一段,是兼容遗留」。内核那栏不看名字,Chrome、Edge、安卓微信都报 Blink(Chromium 内核) / 537.36。

Q:识别爬虫和屏蔽爬虫是一回事吗?

不是。21 条爬虫表只回答「这串字符像不像爬虫」,第 21 条是 bot、spider、crawler、fetcher、httpclient 的泛化匹配;取舍靠 IP 与反向解析。写成 Googlebot 的脚本照样被认成蜘蛛。

Q:页面说明里的微信版本为什么和卡片不一样?

代码捕获 8.0.40.2420 这 4 段,卡片就显示它;工具说明里的 MicroMessenger/8.0.40 少了一段。同一份说明还提小程序,而模板里 miniProgram 出现 0 次,那条 UA 只是被读成 微信(内置浏览器)8.0.44。

📎 相关文章

把质量调到 100 再压一次,图片其实一个字节都没动 2026-10-21 同一个数打两遍,最小公倍数成了 94906266.99999999:先乘后除撞上限的是中间量 2026-10-21 后缀从最后一个点算起:LICENSE、.gitignore、archive.tar.gz 为什么会漏改 2026-10-21 批量建目录的脚本里,编号补零和 CON 这两个坑最容易被忽略 2026-10-21 同一句中文,UTF-8 存 12 字节、GBK 只存 8 字节:编码是怎么被判错的 2026-10-21