一、字体反爬虫定义
字体反爬的实现方式就是通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是明文文字,而是相应的字体编码,通过复制或者简单的采集只能得到一个自定义的编码,无法采集到正确的文字内容。
二、字体反爬虫实现
猫眼是怎么实现的?
我们打开一个电影的页面
然后查看网页源码,
可以看到在评分、票房、口碑这些显示数字的地方,都不是真实的数字,而是一个编码,这些编码通过字体文件转为一个一个的数字,我们可以通过搜索字体属性stonefont来查找,在网页前面部分看到这样的内容:
我们可以看到这里引用的几个字体文件,我们直接下载woff这个文件用来测试和分析。下载到本地保存为e3dfe524.woff,我们在本地建立一个html文件直接使用这个字体文件。内容如下:
将这个html文件和字体文件放同一目录下,用浏览器打开得到如下的显示结果
我们可以看到所有的编码都正常的展示为了数字,虽然看起来是数字,但我们复制出来的却是编码,以此达到防爬虫的目的。
三、原理解析
字体文件是怎么将编码转为数字的呢?我们详细分析一下字体文件,通过在线工具分析一下。
打开这个百度字体编辑器的网页,将字体文件拖到页面上就得到这个,可以看到$E3EC为数字2,我们在页面上编码表示2,后面4位都是e3ec,这个就是真正的编码了。
我们是不是可以直接建立一个编码和数字的映射表,爬取到编码以后通过这个映射表转换一下就可以得到真实数字了呢?如果只有这一个或者少量的字体文件,我们这样当然就可以了。
但是猫眼这里这个办法不太好使。我们从新打开一个页面,字体文件名发生了变化,从新下载字体文件得到432017e7.woff,放到字体编辑器里面:
可以看到这里的2用的编码是f0f0,也就是说字体文件随时可能变化,编码也会变化,在不同的字体文件中,同一个编码可能表示不同的数字,那这个编码映射表就没法做出来了。
我们进一步分析字体文件中编码怎么转为数字的,这里需要用到一个python的小工具fonttools字库工具。
首先需要一个python环境,然后安装这个工具,执行pip install fonttools -y即可安装完成。
然后执行python语句
from fontTools.ttLib import TTFont
font = TTFont('D:\\test\\432017e7.woff')
font.saveXML('D:\\test\\432017e7.xml')
将owff文件转为xml文件,这样我们就可以直接看到里面的内容了。我们打开这个xml文件
可以看到第一部分是字形编码定义,这个字体文件一共包含了哪些编码就在这里定义的,前面id只是编码的顺序号,不是编码代表的数值。真实数字表示在哪里呢?我们往后找,找到TTGlyph部分
这部分就是字形的描点,将这些点连接起来形成完整的图形,就是实际的数字了,我们使用工具将它描绘出来看看。
得到结果:
四、字体反爬虫怎么解决
4.1 单个字体文件:编码映射
如果整个站点只有一个或者少量几个的字体文件,我们就可以定义一个映射表,如上面编码F0F0 对应数字2 ,我们将整个编码都做成相应的映射关系,将采集到的编码通过这个映射表转为真实的文字就可以了。
4.2 随机编码文件字体布局固定:通过字体布局映射
如果编码是随机的,像上面的例子中数字2在两个文件中,是用的不同编码,我们可以通过编码得到布局部分TTGlyph,我们将这个布局部分计算成MD5码,然后制作一个映射表,也可以通过这个映射表转换出真实的文字。
4.3 随机编码字体布局小幅变化:通过字体布局差值百分百幅度映射
4上面的方案前提是字体布局必须要一致才行,如果布局不一致,小幅度变化的情况,我们就可以通过对比两个布局的差值,如果差值在一定数字以下我们就判断两个布局相等,在将布局转换为真实文字。
4.4 随机编码字体布局大幅度变化字形一致:通过字形线条斜率判定
如果布局变化很大,是通过调整文字大小来实现的,那我们可以依次对比描述字体的线条的斜率,如果每个线条的斜率都相差很少,那也可以判断为相同的文字。
五、 以上效果不理想,上终极大招OCR
5.1百度文字识别API:通用文字识别次数5万次,准确率很高,足以使用
5.2只有数字的情况可以考虑图像分类模型,一个小模型准确率轻松到99.95%,单数字识别,加上编码和数字的对应缓存,提高效率。
5.3图片的对比 pyautogui.locate(),或者PyTesseract之类的图片对比工具。
本文暂时没有评论,来添加一个吧(●'◡'●)