声明:文章仅源自个人兴趣爱好,不涉及他用,侵权联系删。
1.提醒:
采集之前找好代理,或者限制抓取频率,不然:
2.网站:
某点评网站,直接说明给链接无法过审,已经审核两次了。。。
3.随便点击一家店铺,查阅评论,顺带检查元素
查看源码:
查看css,定位到字体映射文件:
熟悉的woff文件:
确定的话直接看开发者工具中的font栏,查看字体文件,如下:
这。。。一下三个字体,没办法,先查看文件吧,查看可下载可不下载,但是待会儿还是要用,就直接下载了。
查看字体文件:
仔细观察源码,字体文件,查找关系,其实和之前是一样的:将unicode编码uni+数字字母==>&#x+数字字母+;:
结果,相同的字体,不同的编码,但是都是这些汉字和数字,也就是说点评只对这里面的字进行了处理,观察源码的话也是可以看出来的。
仔细观察刷新会发现,最后相同的字都是处理成同一个格式 。因此,我们只需要构造相应的字典来映射就行了,但是字也不少,7页
5.先用代码抓取评论测试下
def get_source_comment():
url = "http://www.dianping.com/shop/4209136"
cookies = "pgv_pvi=2059; pgv_pvid=3615260; RK=uJCEByPxFa; ptcz=06ac16ad51f2024baa375b35912fd658ed9528c10e35cd96f455d871649b94c0; tvfe_boss_uuid=b8ee5f7a8b849d19; LW_uid=W1e514z751r7J4L4P7d0r2o7h3; mobileUV=1_169325cde2e_20678; _ga=GA1.2.708890391.1552552591; gid=3826ef64-e61f-4dc1-b9ab-faec178fa922; ied_qq=o0297299276; pgv_info=ssid=s6566728952; pgv_si=s7773631488; ptisp=ctc; Qs_lvt_311470=1561080189; Qs_pv_311470=3269254339549629400; vfwebqq=5511eeb85f2e02d71b6813b42cb76bd3431e0908054da0616584501c7af8b7764601579aa30106b4; pgg_uid=41108674; pgg_appid=101503919; pgg_openid=DA23561FBBA13B14B9720C5CAA01F496; pgg_access_token=5868BCF1AD63A73299C732A011588932; pgg_type=1; pgg_user_type=5; Qs_lvt_323937=1571207203; Qs_pv_323937=4088341887126509000; LW_sid=9195y7d1v2h0r7A2v0k6a906I5; open_id=DA23561FBBA13B14B9720C5CAA01F496; luin=null; lskey=null; user_id=null; session_id=null; o_cookie=210570136; pac_uid=1_210570136; _qpsvr_localtk=0.371=589796; uid=88761; mpuv=93683705-63df-45b4-cbe1-f32e7ba247bd"
headers = {
"Cookie":cookies,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}
proxies = random.choice([
代理,如果你没有的话记得限速,别请求太快
])
res = requests.get(url=url,headers=headers,proxies = proxies)
res.encoding = "utf-8"
with open("1.html","a",encoding="utf-8",errors="ignnore") as f:
f.write(res.text)
parse_html = etree.HTML(res.text)
comment = parse_html.xpath('//p[@class="desc"]//text()')
for i in comment:
print(i)
if __name__ == "__main__":
get_source_comment()
打印结果:
所有数据都是请求过来了的,只是有些数据乱码,有些无法显示,从我们保存的文件中,是可以确信数据请求过来了的:
6.获取图片中的所有数字和汉字:
7页汉字,1个1个输入数量一点多,截图借助图像识别API实现 ,外加人工干预:
识别之前记得修改比例,可以提高识别率:
调整前:
调整后:
识别结果,正确率还可以,稍加修改就可以用了
嫌麻烦的话,我这边有一份已经好的,需要的留邮箱,将及时发送
必须确保上图数字汉字的字数顺序的正确,因为这个真的很重要,一个错了那么,就会错一大片
上图的饕餮两字,如果你问我为什么会出现这两个字,说明你还没懂字体破解的方法。
7.思路分析:
1.确认三个字体文件:1个是首次店铺信息的加密字体文件,1个是评论的字体文件,还有1个,那么需要抓哪部分信息就针对某个特定的字体文件进行分析;
2.获取网页,获取response.text如果有需要可以,保存为html
3.获取网页同时保存字体文件,借助上数字汉字字体库,构造相应的字典
4.借助字典映射替换unicode编码文字;
5.获取店铺信息+店铺评论信息等
下面按照思路逐步进行。
8.保存字体文件和相应的文本文件
def saveHtml_saveWoff():#保存相应的html 和 此次的woff字体
url = "http://www.dianping.com/shop/659275097"
cookies = "你的cookies"
headers = {
"Cookie":cookies,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}
proxies = random.choice([
#代理
])
res = requests.get(url=url,headers=headers,proxies = proxies)
res.encoding = "utf-8"
with open("1.html","a",encoding="utf-8",errors="ignnore") as f:
f.write(res.text)
#先抓取css,找到woff文件链接,保存字体
css_href_list = re.findall(r'href="(//s3plus\.meituan\.net/v1.{,100}?)"',res.text,re.S)
if css_href_list:
# "http://s3plus.meituan.net/v1/mss_0a06a471f9514fc79c981b5466f56b91/svgtextcss/5a0bcb14e31bbc0da33526d05daa8a2d.css"
css_href = "http:" + css_href_list[0]
text = requests.get(css_href).text
print(text)
woff_url = re.findall(r'(//s3plus\.meituan\.net/.{,100}?woff)',text)[0]
print("http:"+woff_url)
content = requests.get("http:"+woff_url).content
with open("target.woff","wb") as f:
f.write(content)
9.将字符 和 编码建立对照表
def get_font_map():
font = TTFont("./target.woff")
# fontMap = font.getBestCmap() #getBestCmap()返回cmap表中对应的映射,只不过code字段返回的为十进制数据,如果想转为十六进制,使用hex()内置方法即可
# print(fontMap)
font_names = font.getGlyphOrder() #getGlyphOrder()方法返回所有字符编码名称,按表格顺序提取,类型为列表
print(font_names)
texts = list('''将字体库中的所有汉字复制上来'''.replace(" ","").replace("\n","").replace("\r","").replace("\t",""))
print('字体编码名称数量:', len(font_names))
print('字体编码对应解码字符数量:', len(texts))
num_uni_dict = {}
for i, uni in enumerate(font_names):
num_uni_dict[uni.lower().replace('uni', '&#x') + ';'] = str(texts[i])
print("字体映射字典",num_uni_dict)
return num_uni_dict
10.借助映射表,将网页中的特殊格式字符替换,获取数据:
def get_info():
with open("./1.html","r",encoding="utf-8",errors="ignore") as f:
html = f.read()
# print(html)
map_dict = get_font_map()
for uni in map_dict.keys():
html = html.replace(uni, map_dict[uni])
parse_html = etree.HTML(html)
li_list = parse_html.xpath('//div[@id="comment"]//ul//li')
for li in li_list[0:10]:#我们只要取前10个,其他都是重复的
user_name = li.xpath('./p[@class="user-info"]//a[@class="name"]//text()')
comment = li.xpath('./div[@class="content"]//p[@class="desc"]//text()')
print("用户名:",user_name[0]," 评论:","".join(comment))
最终实现效果:
可以和处理前的评论对比下:
参考: