反爬手段字体加密
以美团民宿中提取的价格为例
思路
-
unicode方式读取html源码,获得相应数字的unicode码
-
找到css中指定标签使用的字体的字体文件和字体的下载地址
补充字体文件知识,css字体知识
-
找到字体文件和字体之间的对应关系
- 如果是每次刷新页面随机使用字体文件
- 还是可能解决的,如果字形是不变的,变的只是字体的unicode编码和文件名。
- 如果字体文件内的字形编码也会改变
- 这种处理本文中不涉及,应该可以采用训练的方式,类似形状的就可以当成是那个形状的而不是像上面那种情况要完全像素位置都完全一样。
- 如果是每次刷新页面随机使用字体文件
核心的点是找到字体文件中和html中unicode中编码中对应的映射关系,还有字体文件中字形数据和 标签(1,2,3…这些)的映射对应关系,所以需要对比两次。处理对比可以使用python的dict来处理,因为刚好是键值对的结构,非常方便。
第一 得到加密的unicode码
如上是提取出的字体加密后的数字的unicode码,第一次接触看不出什么规律,
然后css中找到字体文件(找渲染对应标签的字体文件)
第二 找到字体文件
如上,第一个框是找到的字体文件的地址,可以下载下来
第二个框是找到的类名(css字体语法),对应我们要找的标签的字体
第三
使用字体文件工具打开下载好的字体文件(自行下载)
这儿我使用fontcreator,打开后可以看到字体内的各个字形的属性。
如上图所示,数字上面的编码就是字形编码的key,需要做的就是使用第一步提出到的unicode找到和字体文件这个属性对应的映射关系(因为每次刷新都不一样,所以本文中的编码可能对不上,但是实际如果是同一次的话,实可以发现对应关系的)
第三 给字体文件中每个字形标上标签
这个可以打开字体文件通过眼睛直接给每个打上标签,然后可以把这个标签好的字形文件pickle化存下来,,就不用每次重新打,使用时候直接读取字典就可以
从字体文件中获得字形数据用来备用待对比
# 通过python读取字形编
from fontTools.ttLib import TTFont
def getGlyphCoordinates(filename):
"""
获取字体轮廓坐标,手动修改key值为对应数字
"""
font = TTFont(f'{filename}')
# font.saveXML("bd10f635.xml")
glyfList = list(font['glyf'].keys())
data = dict()
for key in glyfList:
# 剔除非数字的字体
if key[0:3] == 'uni': # 这样对比都行,我感觉有
data[key] = list(font['glyf'][key].coordinates)
return data
读取出字体文件字形数据后再手动给他们打上正确的数字标签(这儿因为0-9一共10个,所以手动式可行的)
根据读取出来的这个编码和刚才工具打开可视化进行对比,标上1,2,3.。。。标好。
然后可以pickle化这个dict,备用
第四步 两次对比
读取html 加密的数字的unicode编码 --》
找到对应的字体文件地址并且下载 --》
读取字体文件并且找到对应与html中数字的编码,提取对应字形数据-》
把提取到的字形数据和已标记的dict进行对比-》
获得对应的标签 -》
得到结果
思路完毕