把字体当锁:字体反爬
本系列一直在讲「同一个字符能对应多个字形」(概念见 字体到底是什么)的常规用法。反过来,这种错位也能被用作对抗手段:斗鱼、猫眼、起点这类站点会给页面挂一份私有字体,故意把码位和字形错排——HTML 里写的是一串乱码(或一个错误数字),浏览器用那份字体一渲染却显示成正确内容。你眼睛看到的对,爬虫抓到的全错。
1 · 为什么爬虫破不了(以及怎么破)
| 人(用浏览器) | 爬虫(读 HTML 文本) | |
|---|---|---|
| 拿到的码位 | 乱码码位 | 同样的乱码码位 |
| 有没有那份字体 | 有,自动下载并按 cmap 渲染 | 通常不解析字体,只取文本 |
| 最终结果 | 看到正确数字 | 乱码 / 被投毒的错数字 |
破解(反反爬)思路:把私有字体一起下载下来,用 fontTools 解析它的 cmap 表与字形轮廓,比对出「码位 → 真实数字」的映射,再把抓到的乱码翻译回去。
对抗会升级:字体会变。点上面的「换一版字体」——渲染照样正确,但映射变了。真实站点常每次请求都下发不同的字体文件(码位随机重排),昨天硬编码的对照表今天就失效。可靠的做法是:每次都从当次的字体文件动态重建映射(按字形轮廓做形状匹配 / OCR),而不是写死一张表。
它和本系列同一原理:正面是「font-variant-* 主动在字形间切换」,反面就是这页「把码位↔字形的错位当锁」——都是 codepoint ≠ glyph 的一体两面。
2 · 相关链接
- 斗鱼爬虫与字体反爬 · cjdev.me——本页蓝本。实战拆解斗鱼如何用自定义字体把数字错排,以及如何下载字体、解析 cmap / 字形轮廓还原真实数据。
- What is a Glyph in Typography? · fontfabric.com——字符 character ≠ 字形 glyph 的基础:同一码位可对应任意字形——这正是字体反爬能成立的根。
- fontTools 文档 · fonttools.readthedocs.io——Python 解析 / 改写字体的事实标准库:读 cmap、导出字形轮廓,反反爬时用它重建码位→数字映射。