浅谈字体反爬虫的一些思路
字数 1030 2025-08-18 11:38:45
字体反爬虫技术详解与实现
0x00 前言
字体反爬虫是一种通过自定义字体文件来干扰爬虫采集网页内容的技术手段。这种技术通过替换网页中关键字符为自定义编码,使得普通爬虫无法直接获取真实文本内容,从而增加数据采集的难度和成本。
0x01 基本原理
字体反爬虫的核心原理是:
- 创建自定义字体文件(TTF)
- 将网页中的特定字符替换为字体编码
- 浏览器通过加载自定义字体正确渲染显示
- 爬虫获取的是编码而非真实文本
0x02 技术优势与局限
优势
- 显著增加普通爬虫的采集成本
- 无需OCR技术即可实现有效防护
- 对用户体验影响较小(加载速度快)
局限
- 不利于SEO优化(搜索引擎可能无法正确索引)
- 需要权衡防护效果与性能影响
0x03 关键技术实现
1. 字体选择策略
关键原则:
- 只选择少量关键字符(约50个)
- 优先选择量词、否定词等改变语义的词
- 示例:数字、"不"、"一"等
原因:
- 全字符替换会导致字体文件过大(几十MB)
- 少量字符字体文件仅几十KB,加载速度快
2. 动态字体编码
进阶防护:
- 每次页面加载随机生成字体编码
- 保持字符形状不变(x,y坐标信息不变)
- 仅改变Unicode编码映射关系
效果:
- 同一字符在不同页面有不同编码
- 爬虫需要建立和维护大量映射关系
- 显著增加爬虫处理成本
0x04 具体实现步骤
1. 准备工作
- 基础字体文件(如微软雅黑)
- 提取关键字符的字体信息
- 准备字体处理工具(fontTools库)
2. 代码实现
# encoding: utf-8
import random
from fontTools import ttx
from fontTools.ttLib import TTFont
def random_unicode(lengths):
# 随机生成Unicode字符集
while True:
shuma = ((str(random.sample(random_list, int(lengths))).replace('[','').replace(']','').replace("'",'').replace(',','').replace(' ','')))
if shuma[0].isalpha():
return shuma
else:
continue
def TTFontsXML(filenames):
# 转换成XML到临时目录
filenametemp = "temp/toolstemp.xml"
font = TTFont(filenames)
font.saveXML(filenametemp)
return filenametemp
def TTFonts(filenames):
# 转换XML为TTF
try:
print("开始转换字体!!!" + filenames)
ttx.main([filenames])
except Exception as e:
print("Something went wrong converting ttx -> ttf/otf:")
print(e)
exit()
def Editfile(fontsjson, files):
random_list = ["a","v","x","s","q","w","e","r","t","y","u","i","o","z","x","c","v","b","n","m","0","1","2","3","4","5","6","7","8","9"]
shuma = ((str(random.sample(random_list, int(25))).replace('[','').replace(']','').replace("'",'').replace(',','').replace(' ','')))
filenametemp = "temp/" + shuma + ".xml"
try:
with open(files, 'r+') as fileOpen:
data = fileOpen.read()
fileOpen.close()
for key in fontsjson.keys():
data = data.replace(str(relationdic[key]), str(fontsjson[key]))
data = data.replace(str(relationdic[key]).upper(), str(fontsjson[key]).upper())
with open(filenametemp, 'w') as f:
f.write(data)
f.close()
return shuma + ".ttf", filenametemp
except Exception as ex:
print(ex)
filenametemp = "error"
filenames = ""
return filenametemp, filenames
3. 完整流程
- 准备基础字体文件和字符映射关系
- 随机生成多套编码映射
- 为每套映射生成对应的TTF文件
- 网页加载时随机选择一套字体
- 将页面内容中的关键字符替换为对应编码
0x05 进阶优化
1. 坐标混淆
- 在随机生成编码的同时,轻微调整字符的x,y坐标
- 使字体文件更难被逆向分析
2. 动态字符选择
- 定期更换防护的关键字符
- 防止爬虫长期积累映射关系
3. 混合防护
- 结合其他反爬技术(如验证码、行为分析)
- 构建多层次的防护体系
0x06 注意事项
- 性能平衡:字体文件大小与防护效果的权衡
- SEO影响:可能影响搜索引擎收录,需谨慎评估
- 用户体验:确保字体加载不影响页面渲染速度
- 维护成本:需要定期更新字体映射关系
0x07 参考资源
- 字体反爬虫实现原理
- GitHub实现代码
- fontTools库文档
通过以上技术实现,可以有效增加爬虫采集数据的难度,保护网站内容安全。实际应用中需要根据具体场景调整防护策略和强度。