Python爬虫--猫眼加密字符



参考文章: 利用自定义web-font实现数据防采集

先挂网站:http://maoyan.com/films/1203

这篇是排名第一的《霸王别姬》电影详情页面,打开 F12 控制台后,去点选其 评分人数累计票房 ,可以看到在页面上能正常查看的数字到了控制台上就变成了n多的小框框,如下图,这是怎么回事呢?

查找字体源

右键查看网页源代码,找到评分人数的位置,我们发现原来这些数字的地方并不是真的小框框,而是一堆看不懂的数字,它们稍微有些规律,都是 &#x 开头的字符,而且一小串字符就代表一个数字,那这是啥意思捏,再来看,其属性是 stonefont 这一类。

在网页源代码中搜索 stonefont ,发现了 @font-face 定义方法。而且还发现,在每次访问刷新页面时,红框中的字体文件地址也会发生改变,因此其加载方式为动态生成字体。

字体解析

现在直接访问字体文件网址,将其下载下来,看看其规律,由于 mac 上不能直接打开 woff 文件,后找到工具百度字体编辑器,在网页中直接打开刚下载的 woff 文件,可以看到下图中对应数字的下方的一小串字符,是不是和之前网页中看到的有些相似,区别只是将 uni 换成了 &#x ,然后将所有字符小写,因此可以找到目前这一个字体文件其中的字体规律。

这里用到了 python 的 fontTools 库,使用它来帮我们解析字体。

安装方法如下:

1
$ pip3 install fontTools

安装好解析库后,在脚本代码中将我们下载的 woff 文件转换成为 xml 文件,方便我们查看,得到下图结果。

上面是整个数字组,从 name=”uniE6DC” 开始依次对应百度字体编辑器中的数字,到这里,已经得到了一套字体的映射规律,但是每次刷新字体文件都会变,这个问题怎么办呢,接着往下看。

接下来查看其中一个字符的字形数据。

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<TTGlyph name="uniE6DC" xMin="0" yMin="-13" xMax="511" yMax="719">
<contour>
<pt x="130" y="201" on="1"/>
<pt x="145" y="126" on="0"/>
<pt x="216" y="60" on="0"/>
<pt x="270" y="60" on="1"/>
<pt x="332" y="60" on="0"/>
<pt x="417" y="146" on="0"/>
<pt x="417" y="270" on="0"/>
<pt x="378" y="309" on="1"/>
<pt x="337" y="349" on="0"/>
<pt x="277" y="349" on="1"/>
<pt x="251" y="349" on="0"/>
<pt x="215" y="339" on="1"/>
<pt x="225" y="416" on="1"/>
<pt x="239" y="415" on="1"/>
<pt x="296" y="415" on="0"/>
<pt x="385" y="474" on="0"/>
<pt x="385" y="535" on="1"/>
<pt x="385" y="583" on="0"/>
<pt x="322" y="646" on="0"/>
<pt x="268" y="646" on="1"/>
<pt x="217" y="646" on="0"/>
<pt x="149" y="584" on="0"/>
<pt x="139" y="518" on="1"/>
<pt x="51" y="533" on="1"/>
<pt x="67" y="623" on="0"/>
<pt x="124" y="670" on="1"/>
<pt x="182" y="719" on="0"/>
<pt x="266" y="719" on="1"/>
<pt x="324" y="719" on="0"/>
<pt x="374" y="693" on="1"/>
<pt x="423" y="669" on="0"/>
<pt x="476" y="581" on="0"/>
<pt x="476" y="485" on="0"/>
<pt x="426" y="410" on="0"/>
<pt x="377" y="388" on="1"/>
<pt x="440" y="373" on="0"/>
<pt x="511" y="281" on="0"/>
<pt x="511" y="211" on="1"/>
<pt x="511" y="118" on="0"/>
<pt x="374" y="-13" on="0"/>
<pt x="270" y="-13" on="1"/>
<pt x="175" y="-13" on="0"/>
<pt x="51" y="99" on="0"/>
<pt x="42" y="189" on="1"/>
</contour>
<instructions/>
</TTGlyph>

在上面代码中,有 x 和 y,好像就是坐标,这些代码好像就是在描述一个字体的形状。来想想,即便是字体文件刷新了,里面神秘代码 uni** 变了,但是最后映射出的字符形状是不会改变的,因此可以说,只要我们找出一套映射规律,我们用第二套字体文件中的 x 和 y 坐标去和第一套中的 x 和 y 对比,只要是相同的数据,也就是“描述一个字体的形状轨迹”是相同的,那就可以正确解析第二套字体,第三套,第四套。。。

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
from fontTools.ttLib import TTFont

font1 = TTFont('4e2d0a51ee699f4d82980ae5927f21e12084.woff')
obj_list1 = font1.getGlyphNames()[1:-1]
uni_list1=font1.getGlyphOrder()[2:]
base_dict = {
'uniEB10': '0',
'uniF819': '4',
'uniED1E': '9',
'uniF02C': '2',
'uniF284': '6',
'uniE8CD': '5',
'uniF75A': '1',
'uniF18C': '7',
'uniE6DC': '3',
'uniF455': '8',
}

font2=TTFont('7204f967cd9de2d94a296851532a76de2076.woff')
obj_list2=font2.getGlyphNames()[1:-1]
uni_list2=font2.getGlyphOrder()[2:]

for uni2 in uni_list2:
obj2 = font2['glyf'][uni2]
for uni1 in uni_list1:
obj1 = font1['glyf'][uni1]
if obj1 == obj2:
print(uni2, base_dict[uni1])

内容替换

最难的地方攻破了,就可以对源代码中的字符进行替换工作了。

完整代码

1
2


-------------本文结束感谢您的阅读-------------

本文标题:Python爬虫--猫眼加密字符

文章作者:Tang

发布时间:2018年11月12日 - 16:11

最后更新:2019年01月20日 - 18:01

原始链接:https://tangx1.com/maoyan_encrypt/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%