上次数独(旁友数独会伐啦?python秒解数独了解下伐啦?)后,老王好像从哪里得到了风声,跟我说少往他们家带扑克牌……意思里你的家庭矛盾都是因为一副扑克牌咯?

行,那我这段时间先歇一歇,来日方长……

那闲着也是闲着,不能去隔壁了,也不能让小胖这双手停下来不是……

那就上点评网找找妹子乐趣,然后就发现点评的反爬做的是真厉害。各个方面的反爬都有涉及,今天我们主要来看一下字体反爬这个玩意儿。

演示环境

  • 操作系统:windows10
  • python版本:python 3.7
  • 代码编辑器:pycharm 2018.2
  • 使用模块:requests,json,re,fontTools

什么是字体反爬?

首选我们先来看一下点评网的评论信息。

从这里可以看到,网页上显示的文字和源码中显示的文字有些出入,并不是一一对应,那继续查看sources中的代码。

可以看到,评论中的某些文字点评网做了特殊处理,这就是所谓的字体反爬。

抓取数据

前面的步骤,我们已经知道点评网对评论内容做了处理,至于是如何处理,这里我们先不管,还是先把数据拿到再说。要是数据都没有拿到,还怎么对数据进行处理呢?

首先使用谷歌的network,对所有请求进行抓包。然后随便搜索一个评论中的某些东西,找到返回的评论数据请求。这里我使用评论人的名字进行搜索,找到其中的请求。有没有觉得这个请求就是返回的评论数据呢。那来验证下。因为这里返回的是一个json数据,可以借助在线json数据查看工具,方便我们对内容进行查看。

将数据复制下来,然后在浏览器中输入网址json.cn


接着就能看到解析出来的json数据。

经过分析,我们知道所有的评论数据都在['reviewAllDOList'],这个集合里装了当前页面前10人的评论数据。这样就可以通过列表遍历的方式拿到相应的数据。
点击这个url的headers,找到请求的url,准备获取数据。

注意:

  • 这个获取到的url只能使用一会儿,过一会就会变化。如果一直使用这个url请求,后面就会得不到数据。所以后续当请求不到数据的时候,就需要刷新网页,获取一个新的url。因为url中有个_token参数是每次变化的。
  • 然后下面框中的内容也必须在请求头中添加上去,否则也还是得不到数据。
  • 这里的重点是在字体反爬,所以其他的一些反爬在这里就不进行赘述了。

至此就找到请求的评论接口数据,直接请求这个url,就能得到我们想要的数据。

import requests
import json
import redef get_page_info():# 首先分析网页,找到返回评论数据的url,这个url就会直接返回评论数据了,但是urlt中的token是会变化的,只能用一会儿,我也不知道一会儿是好久,得不到数据了就换url吧url = 'http://www.dianping.com/ajax/json/shopDynamic/allReview?shopId=131013635&cityId=1604&shopType=10&tcv=7bbq1hdmsj&_token=eJxVTstugkAU%2FZe7nsBcBlBIulBrGxC0MmATTReACoSCFIg4Nv33Thu66Oq8k%2FMJrXMEGymlOhK4nlqwARWqmECg72RimAZOkFkTauoE0v%2BehRqBpN09gn1glkEmhv72YwRSH9BgJpma0hmpJqmmE%2B2348gK5H3f2Ko6DINyLOK6KepMSS%2BV2uWXRkWGFJnJDHkF5KQK5URiOWI8Yv%2BnfflddrsiqyU7ubeQd3r3cQ78Loyof58HQlgrzjXhpejxiHn3Zb%2BO%2BHUjFtOZCMrkOc%2Fi6lYlWbZbrLKeJ1u6RqfxUuaHhWitZb0Oy4RHrnveV0X6%2FhQ0VbPZvu5FOZ%2B91Oi4wwN8fQMlVWIi&uuid=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755&platform=1&partner=150&optimusCode=10&originUrl=http%3A%2F%2Fwww.dianping.com%2Fshop%2F131013635'# 定义模拟请求头headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36','Cookie': 'cy=8; cye=chengdu; _lxsdk_cuid=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b; _lxsdk=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b; _hc.v=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755; s_ViewType=10; __utmz=1.1565010551.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; __utma=1.1978331348.1565010551.1565010551.1565161172.2; __utmc=1; _lxsdk_s=16c6b1cf413-8ae-d6-7b8%7C%7C31','Referer':'http://www.dianping.com/shop/131013635','Connection': 'keep-alive',}# 使用requests库请求url,得到数据json数据result_json_str = requests.get(url,headers=headers).text# 应为返回的数据是里面包含富文本数据,所以首先使用正则表达式删除标签result_json_str = re.sub('<.*?>','',result_json_str)# json数据其实就是一个字符串,所以我们需要先将json转化为python能操作的字典result = json.loads(result_json_str)# 分析得到的数据,得到我们需要的所有评论在result['reviewAllDOList']里面all_review = result['reviewAllDOList']# 遍历得到的所有评论for review in all_review:# 得到用户名username = review['user']['userNickName']# 得到评论内容content = review['reviewDataVO']['reviewBody']# 这里我们就是简单的显示出内容就是了,没有进行储存print('*'*30,'\n',username,content,'\n','*'*30)

运行代码,查看数据,得到的数据果然就是经过处理的。

破解字体反爬

上面虽然拿到了数据,但是这些都是经过处理之后的数据,拿着完全不能用,所以还是得想办法将他给破解下。

首先我们分析网页得知,这些处理之后的数据class都为review,然后他的字体都是'PingFangSC-Regular-review'

猜想这就是点评网自己定义的字体。居然自定义了字体,那么网页中肯定需要加载字体文件,所以果断打开network对字体文件进行抓包。

搜索关键字'PingFangSC-Regular-review',就能找到相应的信息。

我们可以看到,点评网有许多个自定义的字体,这里只需要找自己想要的字体文件即可,即找字体文件的url。只是这些字体文件一般都是.woff或者.ttf结尾的,我们可以将下面的滚动条往右边拖动,就能找到一个.woff的url了。

发现这个url前面是以//开始的,那尝试直接在网址前面加https就行了,那么完整的url就是
https://s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/c667da25.woff

然后在浏览器中输入这个网址,就可以下载一个后缀是.woff的字体文件。

为了方便查看字体文件的内容,我们还需要下载fontCreator这个软件。使用这个软件打开我们刚才下载的文件,就能够看到相应的值。fontCreator官网地址为
https://www.high-logic.com/font-editor/fontcreator

使用fontCreator打开这个woff文件,如下图所示。

我们得把这里面所有的文字按顺序都写出来,并用一个列表保存,空的数据使用’'表示。
是的,你没有看错,将这些文字全部写下。

这些就是字体的形状,我们已经认识了这些字,但我们还得让程序也认识这些字,当然你也可以使用机器学习来识别这些文字,注意:一定要按顺序来,不能遗漏,不然的话对应关系会出错,替换出来的结果也就会出错。

我们把文字敲出来之后,然后需要得到字体形状对应的名字,对应代码字符串。这里需要使用fontTools这个第三方库来处理字体文件。

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

这里我还是很贴心的给大家画了一个图来解释其中的对应关系。

这样就得到了字体的对应关系,但是code是一个整数,而网页上显示的是类似这样的数据,这需要几步转化下:
1、将code变成16进制
2、将最前面的0替换为&#
3、在最后面添加一个;

所以我们也把code按照这个规则进行转换,然后使用re模块。只要找到这样的一个code,就直接替换为文字。这样就能够拿到准确的数据了。

所以,我们最后的get_page()函数的代码如下所示

def get_page(font_names_map=None,font_cmap=None):# 首先分析网页,找到返回评论数据的url,这个url就会直接返回评论数据了,但是urlt中的token是会变化的,只能用一会儿,我也不知道一会儿是好久,得不到数据了就换url吧url = 'http://www.dianping.com/ajax/json/shopDynamic/allReview?shopId=131013635&cityId=1604&shopType=10&tcv=txgmn7z01d&_token=eJxVj81ugkAUhd9ltp3A%2FCskXag1DQq2MmBSTReAOhIEEYg6Nn33Do1ddHXO%2Fe45yb1foPG2wMUIIYYhuOwa4AJsIUsACLrWbLjgRGBHcIdzCLJ%2FTPABhSBtVi%2FA3TCC4ICzzx6EZt5gTgUcCkMelhhLGCS%2FGc9EwKHrate2r9ertc2Tqs4rZWWn0m4Pp9rGFCNMBeXmFGAqZdRXCKOQDFgPih4YTR7a%2Fc2BecKU2lxVxu1mt0i2rD3vw6CNYhTcx6HWzlxKov0M%2BzKm%2Fn3aLWJ5edOT4UiHRfp6UEl5K1OlVpO56mS6RAvs1X5GgyjXjTOtFlGRyng226%2BPR1nwp2S9uhUfda7Go3d99jz0DL5%2FANI8Y5M%3D&uuid=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755&platform=1&partner=150&optimusCode=10&originUrl=http%3A%2F%2Fwww.dianping.com%2Fshop%2F131013635'# 定义模拟请求头,注意,得不到数据的时候,也要将Cookie的值进行替换headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36','Cookie': 'cy=8; cye=chengdu; _lxsdk_cuid=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b; _lxsdk=16c61bb35536e-0e2ab00cb9c2a8-c343162-144000-16c61bb35547b; _hc.v=c59d33fd-e043-a0f5-f6e1-79ae90d14254.1565007755; s_ViewType=10; __utmz=1.1565010551.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _lx_utm=utm_source%3DBaidu%26utm_medium%3Dorganic; __utma=1.1978331348.1565010551.1565010551.1565161172.2; _lxsdk_s=16c70ded480-ab0-fe2-71%7C%7C2','Referer':'http://www.dianping.com/shop/131013635','Connection': 'keep-alive',}# 使用requests库请求url,得到数据json数据result_json_str = requests.get(url,headers=headers).text# 应为返回的数据是富文本数据,所以首先我们先去掉标签result_json_str = re.sub('<.*?>','',result_json_str)# 遍历 字体代码->字体名字 这个字典(code 是一个数字)for code, name in font_cmap.items():try:# 尝试从 字体名字 -> 对应值 这个字典中得到值,防止程序出现KeyError的错误text = font_names_map[name]except:passelse:# 分析网页信息得知,将code变成16进制,并且把最前面的0换成&#,在加上一个';'. 就是网页加密了的字符窜了# 这里就是将59322这样的值变成类似``的值code_str = str(hex(code)).replace('0', '&#', 1) + ';'print(code, code_str, name, text)# 将得到的加密之后的字符串进行替换为相应的数据# result_str = re.sub('需要替换的字符窜','替换为怎样的字符串','从这个字符串里面查找')result_json_str = re.sub(code_str, text, result_json_str)# 处理之后的数据使用json模块变成字典result = json.loads(result_json_str)# 分析得到的数据,得到我们需要的所有评论在result['reviewAllDOList']里面# 因为这里有可能我们别识别出来是一个爬虫了,就会返回其他的数据,比如说你没有登陆啊这样的提示。所以这个时候我们就需要改变我们的额url了。然后重新运行我们的爬虫了try:all_review = result['reviewAllDOList']except:print(result_json_str)raise ValueError('爬取数据失败')# 遍历得到的所有评论for review in all_review:# 得到用户名username = review['user']['userNickName']# 得到评论内容content = review['reviewDataVO']['reviewBody']# 因为我们的重点是字体反爬,所以这里我们就是简单的显示出内容就是了print('*'*30,'\n',username,":",content,'\n','*'*30)

呼。。。我们终于破解了点评网的字体加密。

最后还有一点需要注意,因为这个程序我当天写好之后,能成功的替换相应的字符串,但是当我第二天运行程序的时候,缺不能替换了。

经过分析发现,原来是点评网每天(或许不是每天,每几个小时)应该都会变换字体文件,然后code->name,name->形状也就对应不上了,但是形状->值一定是对应上的,这个不会变化。

那么我们每次运行之前,就直接找到字体文件对应的url,然后先将这个文件下载保存到本地,再运行我们的爬虫即可。

**注意:**这个字体文件的url是会变化的,也就是点评网的服务器上每个字体应该存放了好几个不同的字体文件。所以我们每次运行都需要先去找到对应的字体文件的url。

from urllib.request import urlretrievedef get_font_file():url = 'https://s3plus.meituan.net/v1/mss_73a511b8f91f43d0bdae92584ea6330b/font/c667da25.woff'urlretrieve(url,'font.woff')

这里说一下urlretrieve函数的用法吧。

urlretrieve:将网络上的文件下载下来,保存到本地。第一个参数为url,第二个参数为保存到本地文件的文件名。

使用这个函数我们可以很方便的下载网络上一些文件,图片等。
最后我们来看一波运行结果吧。

不得不服点评网,反爬虫做的真是厉害。。。

全部代码已上传至Github:https://github.com/MiracleYoung/You-are-Pythonista/tree/master/PythonExercise/App/dianping_spider

破解点评网字体反爬,深入挖掘系统背后的原理相关推荐

  1. 终于解决大众点评的字体反爬了!

    为了防止自己忘了,还是在这里写个大概过程吧 还不完善,之后再改 之前虽然我接触过一个字体反爬的网站,但是比较简单的,字体文件直接就在源码里,大众点评的不一样,我们先去网页看一下,可以发现,评价数,人均 ...

  2. 小白也可以看会的破解抖音字体反爬

    现在的网站,处处都是反爬,我们这些爬虫的经常需要和他们斗智斗勇,就看谁更厉害.这不,就连字体也弄成了反爬,而且还不止一个网站,常见的就有猫眼和汽车之家.不过,字体反爬也没有用,毕竟我们会破!哈哈. 抖 ...

  3. python爬虫: 使用knn算法破解猫眼动态字体反爬

    猫眼字体反爬 动态变化的字形使用阈值判断误差率较大,甚至看到有的老哥使用ocr去搞-,大概两个月前,第一次看到有大佬使用knn算法搞字体反爬(源码地址),听说效果不错,一直没有时间去尝试,不仅仅是没有 ...

  4. 破解58同城字体反爬

    1. 前言 最近接了一个私活,破解58同城的css反爬.(被鸽了)现在决定把它开源出来,以便大家参考学习. 2. 主题 首先,打开页面,了解到这部分信息是有字体加密的.如下图: 这部分信息包含 性别 ...

  5. python爬取大众点评字体_python爬取大众点评解决字体反爬

    今天我们弄一下大众点评 学习阶段,我们要抱着学习的目的 重点是思路,做爬虫就不要想着一劳永逸了 方法公开,人家就换了 知识是你自己的,学到了,他换不掉 好了,我们开始吧 网站展示 https://ww ...

  6. 大众点评数据信息获取——字体反爬

    大众点评数据信息获取--字体反爬 大众点评的字体反爬算是比较常见的,这次来学习一下相关字体反爬的技巧 以店铺的评论页面和店铺列表页面进行研究,分别对应了css字体映射,woff字体加密的反爬虫手段. ...

  7. 爬取在线全面小说网小说(字体反爬)

    小说网字体反爬 小说网址:https://www.tianhuajinshu.com/ 在手机端浏览小说时,有时候开启无图模式发现部分文字加载不出来,还有的不能使用浏览自带的阅读模式进行阅读,也就是无 ...

  8. 爬虫逆向学习(二):那些年遇到的花式字体反爬

    常见字体反爬破解策略 CSS偏移反爬虫 案例场景 破解策略 SVG字体反爬 案例场景 破解策略 自定义字体反爬 案例场景 破解策略 CSS偏移反爬虫 案例场景 css偏移反爬虫是通过样式left偏移覆 ...

  9. 【机器学习】KNN算法及其用KNN解决字体反爬

    KNN算法及其用KNN解决字体反爬 关于KNN算法 概要 简介 原理 KNN算法Python实现 KNN解决字体反爬 web-font介绍 例子 最后 关于KNN算法 概要 K最近邻(kNN,k-Ne ...

  10. python爬取猫眼遇到动态字体反爬

    前一段时间,爬取了58同城,发现当时的网页对数字有字体反爬虫,然后废了九牛二虎之力找到了规律,终于破解了反爬虫,后来发现猫眼的这个网页虽然使用了字体反爬,但是和原来的58同城还是有很大的差别,后来了解 ...

最新文章

  1. 疑问:undistortPoints()与remap()畸变校正后,结果相差很大
  2. Linux命令的实现 -- ls pwd cd
  3. nginx lua 配置cc 防攻击-使用lua 配置黑白名单
  4. STM32中stm32f0xx_flash.icf文件的作用详解!
  5. 剑指Offer Ⅱ 003.二进制加法(力扣剑指Offer专项突击版——整数_3)
  6. 怎么做应力应变曲线_做冲压材质分析很重要,材料性能分析汇总~
  7. WEB_面试题_第三阶段
  8. python在线包安装mysql_python安装mysql的依赖包mysql-python操作
  9. 20210224:力扣第229周周赛
  10. 【java笔记】函数式编程
  11. 几个北邮和交大学霸的公众号,值得学习
  12. 苹果6访问限制密码4位_1Password for Mac(专业密码管理工具)
  13. 计算机如何执行(运行)程序
  14. 看脸的世界:牙齿整齐找工作更容易
  15. 焕然一新的 Vue 3 中文文档要来了
  16. c#机器人聊天软件_C#winForm 聊天只能机器人(完整版)
  17. C#正则表达式测试小工具
  18. 为什么把人称呼为“总”?
  19. java实现图片下载
  20. Python上手就有

热门文章

  1. vscode下载很慢问题处理
  2. HCIP-RS H12-221-题库包含答案 1-50题(不定期更新剩余题目)
  3. 命令行 降低IE版本 IE11降到IE8
  4. mybatis支持拼音、汉字模糊查询
  5. 文本聚类 java_【Java】文本聚类
  6. springboot跨域处理
  7. matlab 系统辨识,系统辨识的Matlab实现方法(手把手)..docx
  8. HTTP协议抓包分析
  9. 十四五规划下建筑企业智慧建造数字化转型规划战略
  10. 记自己在用友的三个月实习经历