猫眼电影某页面动态字体bypass

注意本文的版权声明。

0x00 起手

主要介绍了笔者对猫眼电影https://piaofang.maoyan.com/?ver=normal的动态字体反爬的分析工作和处理。这种字体反爬的手段还经常运用在小说网站中,优点是因为字体非常规字体,即便使用了浏览器模拟访问,也取不到直接数据。不过笔者目前基本已经可以做到自动完成数字和字母,汉字有待进一步测试调试。

当然,猫眼其实有一个更好爬的页面:https://piaofang.maoyan.com/dashboard。这里只是知难而上地介绍技术,不爬什么票房。

0x01 取到字体

在这里插入图片描述

这里最开始的截图,浏览器自带调试器network下的浏览器渲染预览,在第一次请求目标URL的时候,数据包已经取回了关键位置的内容。不过很明显的,可以看到有些字体和其他的不一样,主要是数字发生了变化。通常这个样子说明是数据包里自带有JS或者CSS,并执行了。直接复制这些数据,会变成方块,和Linux下丢失了不支持中文时的表现得差不多。看源码,这里其实是一种编码。
在这里插入图片描述
向上定位,找到了加载渲染的JS,很明显有一个base64编码的标记。后面的数据通过解码得到的是一个对应ASCII为wOFF开头的bin数据,这个开头是一种字体文件格式的魔数。这种编码对应了这个字体中的某个字符,然后浏览器支持这种标准,就会渲染出来对应的字体。
在这里插入图片描述
然后写脚本发送请求数据,注意数据包一定要有UA头才能取到数据。经过一段时间这些字体编码是会变化的,这就是一开头提到的动态。使用工具提取字体xml内容,因为使用python编写,所以作者在这里是调用fontTools模块提取。

a = base64.b64decode(b64data)
with open('tmp','wb') as f:
    f.write(a)
tmp = TTFont('tmp')
tmp.saveXML('end.xml')

xml里每个字符有一个标签,子标签中会有字体定型的关键坐标信息。下一步的工作就是把这些点取出来,有了这些点,字体的骨架就有了。最开始使用的办法是通过python中的matplotlib模块进行画线,matplotlib本身的强大画图功能对于这种工作来说是小试牛刀。不过有几个字符因为点的顺序,总是会有多余的连线,比如0这样的先画外圈再画内圈,内外之间就多一条连线,而且两个圈还不闭合。这个问题搁置了一段时间没法解决。当时,有两种处理办法:一种是图片出来之后人工改一改图片名,然后再用程序替换字体。另外一个是使用OCR,不过这时还是些点或者一些线,根本不符合OCR应用的场景。

0x02 渲染字体

后来翻看matplotlib gallery的时候看到matplotlib中plot的.fill()函数可以画封闭图形,比如给出一个环上的点集,可以此画出一个圈。于是决定试试这个函数能否画出来想要的结果,运行之后还是不错的。虽然没有任何抗锯齿机制,就是单纯地描了描点,不过已经解决了关键问题。推荐使用黑色填充,和白色的地面成对比,后面处理效果更好。浏览器如何把字体渲染得那平滑的,查了一些算法都没有详细的说明,欢迎大佬不吝赐教。
在这里插入图片描述
之后就是如何让OCR识别了。一般OCR可以识别的字体都比较小。是数字的话,应当注意高度比宽度大一些,显得瘦高一些。这两个参数的变化十分影响识别的效率,通常长/宽==1的情况没有长/宽 > 1的好。当然做些预处理结果可能会更好。对于猫眼电影来说,变化的字体都是数字,识别成了O或者o其实可能是0。这里使用了tesseract。从前面xml中取到映射关系,直接变换过来,就可以替换编码为正常数字了。(长宽比和OCR用的参数非常重要)
在这里插入图片描述

0x03 后续处理

关于动态字体替换了汉字的情况,目前没有测试,推测性质应该差不多。极端情况下,多采集样本,人工标记做成字体训练OCR增强它的识别力应该能对付了,毕竟不是手写字识别。

只要页面能够被浏览,编码或者未经数学验证别出心裁自创的加密都不可能防得住,bypass只是时间的问题。曾经煎蛋被爬虫毒害得很深,他们自己写了一个加密,后来逆出来了。现在知道这些徒劳,只是用base64编码阻挡一下通用爬虫和初学者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值