爬虫遇到字体动态加密?手把手破解

↑↑↑点击上方“蓝字”,关注极客猴html

若是你喜欢极客猴,能够把我置顶加为星标python


阅读文本大概须要 6 分钟。正则表达式

咱们在上一篇文章   《破解大众点评的字体加密 中提到了,大众点评只是静态字体加密,此次咱们抱着学习的态度以猫眼电影为例讲讲如何破解字体动态加密。

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

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

https://maoyan.com/board/1函数

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


让咱们回忆一下破解大众点评的步骤:
一、下载网站font字体包
二、将font字体包中导入FontEditor 观察获得乱码与数字的关系
三、前缀替换,并将字体名字和它们所对应的乱码构成一个字典
四、根据字典将加密的数字替换


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



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


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



其中A字体的1对应的是【uniECC8】
       B字体的1对应的是【uniE5FD】
       C字体的1对应的是【uniEE6C】


并没有规律。


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


#.woff文件转换成.xml文件
from fontTools.ttLib import TTFont
font = TTFont('./.woff')
font.saveXML('A.xml')


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



不少网上的教程到这里就结束了,由于按理说这三个字体的统一数字对应的XY坐标应是同样的。


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


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


因此咱们容许在必定范围内的差别就算同样就好啦。


因为有负数,经过abs函数取绝对值


#对比两个坐标的差别
def compare(AA, BB):
    for i in range(5):
        if abs(AA[i][0] - BB[i][0]) < 80 and abs(AA[i][1] - BB[i][1]) < 80:
            pass
        else:
            return False
    return True
#True则可视为是同一个字

这样咱们就以某字体基准,不管如今实时的字体是哪个,只要下载下来,再与该字体进行坐标差别对比,类似的就是同一数字。


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



咱们下面尝试一下:
一、将新下载的字体文件与base_font对比,找到对应关系
二、前缀替换,并将字体名字和它们所对应的乱码构成一个字典
三、根据字典将加密的数字替换


# 字体解密 
def modify_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']
    for i in range(1, len(unilist)):
        newGlyph = newFont['glyf'][unilist[i]].coordinates
        for j in range(len(base_unicode)):
            baseGlyph = basefont['glyf'][base_unicode[j]].coordinates
            if compare(newGlyph,baseGlyph):
                numlist.append(base_num[j])
                break
    rowList = []
    for i in unilist[2:]:
        i = i.replace('uni''&#x').lower() + ";"
        rowList.append(i)

    dictory = dict(zip(rowList, numlist))
    for key in dictory:
        if key in html:
            html = html.replace(key, str(dictory[key]))
    return html
# 返回解密后的html
四、利用正则表达式获取数据
# 正则
def parse_page(html):
    pattern = re.compile('
  • .*?board-index-.*?>(.*?).*?src="(.*?)".*?'
                             + 'title="(.*?)".*?class="star">(.*?)字体


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


    .*?'
                             + '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)
    return data


运行一下。



get。


本文相关爬虫代码,仅供学习交流:https://t.zsxq.com/RVn6qBU

END



精彩推荐
如何将 Pycharm 打造得更称手
微软也爱 Python!VS Code Python 全新发布!
受用一辈子的高效 PyCharm 使用技巧(六)



技术·思考·职场



长按二维码,添加关注!

本文分享自微信公众号 - 极客猴(Geek_monkey)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索