首页 > 科技 > 超级反爬手段解密:python处理猫眼字体动态加密

超级反爬手段解密:python处理猫眼字体动态加密

现在网站应对爬虫的手法越来越多,很多能够看到的数据也没法通过代码直接获取。

我们在之前的文章 中提到了,大众点评是用了静态字体加密。这次我们抱着学习的态度,以猫眼电影为例来探讨下如何应对动态字体加密。

没有了解过字体加密的小伙伴可以先看看上一篇,本文与上一篇重复的部分就不细讲了。

我们打开猫眼电影票房榜单的首页

很明显,猫眼电影的榜单进行了字体加密。



让我们回忆一下破解大众点评的步骤:


1、下载网站font字体包

2、将font字体包中导入FontEditor 观察得到乱码与数字的关系

3、前缀替换,并将字体名字和它们所对应的乱码构成一个字典

4、根据字典将加密的数字替换

然而,右键刷新页面,字体文件一直在变:



为了探究一下,我们随便下载3个字体文件,对比看看能不能发现其中的规律。

分别重命名为A.woff,B.woff,C.woff,将他们依次导入FontEditor中打开



其中A字体的1对应的是【uniECC8】

B字体的1对应的是【uniE5FD】

C字体的1对应的是【uniEE6C】

并无规律。

我们再将.woff文件转换成.xml文件,看看字体结构有没有相似之处:

#.woff文件转换成.xml文件

fromfontTools.ttLibimportTTFont

font = TTFont('./.woff')

font.saveXML('A.xml')

每一个编码都对应一个TTGlyph对象,而许多行的XY坐标点最终绘制成数字。





很多网上的教程到这里就结束了,因为按理说这三个字体的统一数字对应的XY坐标应是一样的。

这说明猫眼最近又新挖了一个坑,继续填坑。

看看上面的三个图,其实他们的XY坐标差异并不大。

所以我们允许在一定范围内的差异就算一样就好啦。

由于有负数,通过abs函数取绝对值

#对比两个坐标的差

defcompare(AA, BB):

foriinrange(5):

ifabs(AA[i][0] - BB[i][0])

pass

else:

returnFalse

returnTrue

#True则可视为是同一个字

这样我们就以某字体基准,无论现在实时的字体是哪一个,只要下载下来,再与该字体进行坐标差异对比,相似的就是同一数字。

在网上找了一张思路图,方便大家理解:



我们下面尝试一下:

1、将新下载的字体文件与base_font对比,找到对应关系

2、前缀替换,并将字体名字和它们所对应的乱码构成一个字典

3、根据字典将加密的数字替换

# 字体解密

defmodify_html(newFont, html):

basefont = TTFont('./base_font.woff')

unilist = newFont['cmap'].tables[0].ttFont.getGlyphOrder()

numlist = []

base_num = ['6','3','7','1','5','9','0','4','2','8']

base_unicode = ['uniF0DA','uniE907','uniED01','uniEAE1','uniF206',

'uniE455','uniF401','uniE19C','uniEB76','uniF855']

foriinrange(1, len(unilist)):

newGlyph = newFont['glyf'][unilist[i]].coordinates

forjinrange(len(base_unicode)):

baseGlyph = basefont['glyf'][base_unicode[j]].coordinates

ifcompare(newGlyph,baseGlyph):

numlist.append(base_num[j])

break

rowList = []

foriinunilist[2:]:

i = i.replace('uni','').lower() +";"

rowList.append(i)

dictory = dict(zip(rowList, numlist))

forkeyindictory:

ifkeyinhtml:

html = html.replace(key, str(dictory[key]))

return html

# 返回解密后的html

4、利用正则表达式获取数据

# 正则defparse_page(html):

pattern = re.compile('

.*?board-index-.*?>(.*?).*?src="(.*?)".*?'

+'title="(.*?)".*?class="star">(.*?)

.*?releasetime">(.*?).*?'

+'realtime".*?stonefont">(.*?).*?'

+'total-boxoffice".*?stonefont">(.*?).*?

', re.S)

items = re.findall(pattern, html)

data = pd.DataFrame(items,columns=['index','image','title','star','releasetime','realtime','total-boxoffice'])

data['star']=data['star'].str[3:]

data['releasetime']=data['releasetime'].str[5:]

print(data)

returndata

运行一下。



票房数据get✔️

最后,小编想说:我是一名python开发工程师,整理了一套最新的python系统学习教程,想要这些资料的可以关注私信小编“01”即可,希望能对你有所帮助

本文来自投稿,不代表本人立场,如若转载,请注明出处:http://www.sosokankan.com/article/1892523.html

setTimeout(function () { fetch('http://www.sosokankan.com/stat/article.html?articleId=' + MIP.getData('articleId')) .then(function () { }) }, 3 * 1000)