大众点评字体反爬
声明:博客内容不得用于商业用途,仅做学习交流,如果侵犯了您的利益和权益,请邮箱联系我,我将删除该博客。
加密种类
目前大众点评字体反爬有两种:
- css 字体映射(svg);
- woff 字体加密。
1.CSS 字体映射
商家评论页面中,商家地址、电话、用户评论都采用了 CSS 字体映射加密。
例如:http://www.dianping.com/shop/G9TSD2JvdLtA7fdm/review_all
页面中
用户评论字段:
商家电话字段:
商家地址字段:
可以发现这三处部分文字缺失,缺失处只有固定格式标签,规律如下:
- 地址部分缺失文字的标签为
<bb class=".*?"></bb>
- 电话部分缺失文字的标签为
<cc class=".*?"></cc>
- 评论部分缺失文字的标签为
<svgmtsi class=".*?"></svgmtsi>
并且可以看到右侧 style 栏,对应 class 的样式如下:
以用户评论区举例分析:
svgmtsi[class^="zpe"] {
width: 14px;
height: 24px;
margin-top: -14px;
background-image: url(//s3plus.meituan.net/v1/mss_0a06a47…/svgtextcss/fbdd5d3….svg);
background-repeat: no-repeat;
display: inline-block;
vertical-align: middle;
}
.zpef38 {
background: -364.0px -373.0px;
}
发现所有 class 以 “zpe” 开头的 svgmtsi 标签都有一个 background_image
的属性,其值为一个后缀为 .svg
的 url,此处为:
http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/fbdd5d341374634b91fa99fed6d3a2c5.svg
.zpef38 { background: -364.0px -373.0px; }
的标签在页面中显示为汉字 和
。
打开上面的 url,可以看大如下页面:
HTML 格式如下:
标签 <style>
内容如下:
字体大小为:font-size: 14px
标签 <defs>
内容如下:
发现除了 id 递增外,每一行只有 d="M0 (.*?) H600"
括号里的值在递增变化。
标签 <text>
内容如下:
<textPath>
标签中 xlink:href = '#num'
为 css 选择器,绑定了 <defs>/<path>
的 id;
<textPath>
值为一串汉字字符串。
到这里是不是全都明白了。。。哈哈哈哈
我们上面提到的.zpef38 { background: -364.0px -373.0px; }
的标签在页面中显示为汉字 和
。
x: -364.0px,y:-373.0px
取 y 的绝对值 373,和d="M0 (.*?) H600"
括号里的值做比较,取大于等于 y ,并且最接近 y 的那一行
这里 396 大于 373并且最接近373,此处的 id = 9,我们找到下面 <textPath xlink:href='#9'>
的这一行,
对应的字符串如下:
考貌漫夸绢屯嫩化央疲瓣况慢搂命墨像冷十馒摘桐劫拥孙准和改图导玩僚足毯斑
取 x 的绝对值 364/字体大小 = 364/14 = 26
[(0, '考'), (1, '貌'), (2, '漫'), (3, '夸'), (4, '绢'), (5, '屯'), (6, '嫩'), (7, '化'), (8, '央'), (9, '疲'), (10, '瓣'), (11, '况'), (12, '慢'), (13, '搂'), (14, '命'), (15, ' 墨'), (16, '像'), (17, '冷'), (18, '十'), (19, '馒'), (20, '摘'), (21, '桐'), (22, '劫'), (23, '拥'), (24, '孙'), (25, '准'), (26, '和'), (27, '改'), (28, '图'), (29, '导'), (30 , '玩'), (31, '僚'), (32, '足'), (33, '毯'), (34, '斑')]
下标为 26 的字符就是汉字 ‘和’。
2.WOFF 字体加密
页面:http://www.dianping.com/shenzhen/ch10/g117
图中左侧类似这样的标签:<svgmtsi class="address"></svgmtsi>
,右侧为对应的 css 文件,点进去看看:
可以找到对应的 woff 字体链接,可以使用在线工具打开看看,类似这样:
这样其实就出来,把对应的汉字和编码,组成一个码表字典,去替换<svgmtsi class="address"></svgmtsi>
中的 
,600个字手动去做映射是不可能做的,打死都不做的,并且这个 woff 文件应该每天都会更新,所以动态生成映射字典是问题的关键。
思路可以参考这位老哥的博客:
https://blog.csdn.net/weixin_43752839/article/details/98314821#commentBox
这位老哥的代码我跑了一下,发现ImageFont.truetype()
无法加载 woff 字体文件,一直报 OSError 异常,ttf 类型的文件可以正常加载,于是在 github 上找到了一个 woff 转 ttf 的项目,成功处理。
总结:
- 以上两种解密过程,已用 python3 实现;
- 项目地址:
https://github.com/naiveliberty/DaZhongDianPing
- 如果对大家分析问题有些许帮助,请各位大佬多多start呀!