字体加密?看我如何破解某点评反爬逻辑!

共 9857字,需浏览 20分钟

 ·

2021-01-01 03:23

大家好,在上周发布的Python爬取上万条大众点评数据,解读一线快餐品牌背后的秘密中,提到了大众点评网商家数据的爬取方法,很多读者表示感兴趣,本文就来好好聊一下如何破解字体加密,拿到我们想要的数据!

以爬取商家地址数据为例,我们打开大众点评网定位合肥,并搜索沙县小吃,之后在跳转的搜索结果页面中按下F12

现在定位到任一商家的地址,如上图所示,查看地址部分对应的源码发现,这部分的文字被包在svgmtsi标签中,并且大多数的字都是方框,根据文字长度我们不难判断出来,每一个小标签对应了一个文字,很明显,该网站对字体进行了加密!

所以下一步的任务很明确了「破解这个小方块

在6月份,我曾经转载过夜幕团队的一篇文章一线大厂在用的反爬虫方法,看我如何破了它,在那篇文章中介绍了基于大众点评的「SVG映射反爬虫绕过实战」,不过现在大众点评已经升级为字体加密反爬,不过解决方法大同小异,我们继续。

既然是字体加密,我们找到对应的字体

发现地址部分的字体是定义在CSS文件中,进一步点击打开对应的css文件

可以看到使用的是名为1d742900.woff字体文件,不管这个字体文件有多么神秘,既然给了地址,我们将它下载下来并打开(Windows下可以使用FontCreator等字体软件,当然也有很多在线的字体编辑软件)

可以看到这份字体一共有603个glyphs,并且每一个字有唯一对应的unicode编码

现在我们查看地址部分源码

接着使用requests请求该页面并提取第一个地址对应的文字信息

我们可以发现,除了未被加密的文字,所有加密的文字都以unicode编码记录,并且这个源码与我们上面打开的字体文件对应,不信我们验证一下,第一个被加密的文字为路

请求得到的编码为\uef66,我们回去字体文件中查找

后四位刚好与\uef66对应!

所以接下来我们的思路就非常明确了,建立文字与编码的映射也就是说,将这603个字转换为编码,再用这个编码去匹配被加密的文字

不过由于这603个字是在字体文件中无法直接导出,因此不论我们是用手敲还是OCR识别,都比较麻烦,幸运的是网上有人已经将这些字体整理出来了,所以我们直接拿来用即可!

下一步就是使用fontTools这个包解析woff文件,并构建后面匹配用到的字典,代码如下:

from fontTools.ttLib import TTFont
    
font = TTFont(font_name)
font1=font.getGlyphOrder()[2:] #解析字体
font1 = [font1[i][-4:] for i in range(len(font1))] #取最后四位编码

font2 = ['1''2''3''4''5''6''7''8',
    '9''0''店''中''美''家''馆''小''车''大',
    '市''公''酒''行''国''品''发''电''金''心',
    '业''商''司''超''生''装''园''场''食''有',
    '新''限''天''面''工''服''海''华''水''房',
    '饰''城''乐''汽''香''部''利''子''老''艺',
    '花''专''东''肉''菜''学''福''饭''人''百',
    '餐''茶''务''通''味''所''山''区''门''药',
    '银''农''龙''停''尚''安''广''鑫''一''容',
    '动''南''具''源''兴''鲜''记''时''机''烤',
    '文''康''信''果''阳''理''锅''宝''达''地',
    '儿''衣''特''产''西''批''坊''州''牛''佳',
    '化''五''米''修''爱''北''养''卖''建''材',
    '三''会''鸡''室''红''站''德''王''光''名',
    '丽''油''院''堂''烧''江''社''合''星''货',
    '型''村''自''科''快''便''日''民''营''和',
    '活''童''明''器''烟''育''宾''精''屋''经',
    '居''庄''石''顺''林''尔''县''手''厅''销',
    '用''好''客''火''雅''盛''体''旅''之''鞋',
    '辣''作''粉''包''楼''校''鱼''平''彩''上',
    '吧''保''永''万''物''教''吃''设''医''正',
    '造''丰''健''点''汤''网''庆''技''斯''洗',
    '料''配''汇''木''缘''加''麻''联''卫''川',
    '泰''色''世''方''寓''风''幼''羊''烫''来',
    '高''厂''兰''阿''贝''皮''全''女''拉''成',
    '云''维''贸''道''术''运''都''口''博''河',
    '瑞''宏''京''际''路''祥''青''镇''厨''培',
    '力''惠''连''马''鸿''钢''训''影''甲''助',
    '窗''布''富''牌''头''四''多''妆''吉''苑',
    '沙''恒''隆''春''干''饼''氏''里''二''管',
    '诚''制''售''嘉''长''轩''杂''副''清''计',
    '黄''讯''太''鸭''号''街''交''与''叉''附',
    '近''层''旁''对''巷''栋''环''省''桥''湖',
    '段''乡''厦''府''铺''内''侧''元''购''前',
    '幢''滨''处''向''座''下''県''凤''港''开',
    '关''景''泉''塘''放''昌''线''湾''政''步',
    '宁''解''白''田''町''溪''十''八''古''双',
    '胜''本''单''同''九''迎''第''台''玉''锦',
    '底''后''七''斜''期''武''岭''松''角''纪',
    '朝''峰''六''振''珠''局''岗''洲''横''边',
    '济''井''办''汉''代''临''弄''团''外''塔',
    '杨''铁''浦''字''年''岛''陵''原''梅''进',
    '荣''友''虹''央''桂''沿''事''津''凯''莲',
    '丁''秀''柳''集''紫''旗''张''谷''的''是',
    '不''了''很''还''个''也''这''我''就''在',
    '以''可''到''错''没''去''过''感''次''要',
    '比''觉''看''得''说''常''真''们''但''最',
    '喜''哈''么''别''位''能''较''境''非''为',
    '欢''然''他''挺''着''价''那''意''种''想',
    '出''员''两''推''做''排''实''分''间''甜',
    '度''起''满''给''热''完''格''荐''喝''等',
    '其''再''几''只''现''朋''候''样''直''而',
    '买''于''般''豆''量''选''奶''打''每''评',
    '少''算''又''因''情''找''些''份''置''适',
    '什''蛋''师''气''你''姐''棒''试''总''定',
    '啊''足''级''整''带''虾''如''态''且''尝',
    '主''话''强''当''更''板''知''己''无''酸',
    '让''入''啦''式''笑''赞''片''酱''差''像',
    '提''队''走''嫩''才''刚''午''接''重''串',
    '回''晚''微''周''值''费''性''桌''拍''跟',
    '块''调''糕']
    
font_data = dict(map(lambda x,y:[x,y],font1,font2))

现在文字和编码的一一对应关系就建立起来了!

最后就是将请求得到的源码,根据字典的键进行匹配,得到解密后的真实地址

font_list = [i for i in addr_text] #提取编码
font_list = [str(i.encode("unicode_escape"))[-5:-1] if len(repr(i))>3 else i for i in font_list] #提取后四位

addr = ''.join([font_data.get(i) if len(i)>1 else i for i in font_list]) #匹配
    
addr = city + addr

代码很简单就不做过多讲解了,唯一需要注意的就是我们直接从网上请求返回的\uxxxx虽然是str格式,但是确实unicode编码,所以需要先使用repr进行转义后方可进行截断!

现在来测试一下

可以看到,该页所有地址信息全部被正确提取出来(关键信息已经打码)!

至此我们就成功破解大众点评网地址信息的字体加密,当然例如评分、均价等信息,我们可以如法炮制,只不过换了一个字体罢了,本文不在赘述!

搞定字体加密之后,我们就可以轻松的提取想要的信息,不过由于点评网的反爬机制,在爬取时务必要注意使用代理ip、控制频率等手段来防止被检测到!爬取的数据也切勿用于任何盈利及非法等用途!

-END-



扫码添加早小起

1. 回复「进群」进入Python技术交流群

2. 回复「Python」获得Python技术图书

3. 回复「习题」领取Python数据处理200题




浏览 56
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报