python爬虫实战—爬取大众点评评论(加密字体)

1.首先打开一个店铺找到评论

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

2.分析网页

查看到下面有些字体经过加密处理 刷新页面会发现 每一次加密的字体是不一样的

3.发送请求获取数据

查看网页源代码 查看所有css 发现这个css就是我们想要用的文件 那么现在我们就要用代码来获取到这个css文件的urlCookie自行更换
代码实现:

class DownComment:def __init__(self):# 爬取数据cookie user—agentself.headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6"") AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36","Cookie": 'fspop=test; _lxsdk_cuid=1741e6d406ec8-07a55a88376aea-31657305-13c680-1741e6d406ec8; _lxsdk=1741e6d406ec8-07a55a88376aea-31657305-13c680-1741e6d406ec8; _hc.v=686b52bb-73c6-234a-0599-c881b393882d.1598238311; Hm_lvt_602b80cf8079ae6591966cc70a3940e7=1598238354; cityid=838; default_ab=index%3AA%3A3; switchcityflashtoast=1; s_ViewType=10; ll=7fd06e815b796be3df069dec7836c3df; ua=dpuser_7474971098; ctu=4cc4b902d60a40f51447c2d6d386233260a8f2e43bf520fb73056aa472dfbb35; aburl=1; Hm_lvt_dbeeb675516927da776beeb1d9802bd4=1598270129; Hm_lpvt_dbeeb675516927da776beeb1d9802bd4=1598270129; cy=1; cye=shanghai; dper=627d6236bc87ce08b3d5c48661e5572f504bcf9938fee451ebd4566d8234bc5b1ad10791c702986d1398b6a838a4e550619d42c3d68d02b0f53cf4ed5c38702b47d41ef5f7e7d368892b8be8a46b2eb844582afbcc419e5e28df0a92c1df589e; uamo=17643530928; dplet=7731f44d071e7840935794d1a9ae35d4; Hm_lpvt_602b80cf8079ae6591966cc70a3940e7=1598342331; _lxsdk_s=1742497507a-072-c5-68e%7C%7C766'}# 爬取大众点评的urlself.url = None# 页面返回的textself.text = None# css文件的内容self.css_content = None# css文件的urlself.css_url = None# 取出的字体文件的内容self.svg_content = None# 用来存储每一个字的映射关系的列表self.font_d_l = list()# 用来存储坐标映射self.position_l = list()# 字体位置self.position_list = list()# 数据self.data = list()def down_css(self):"""获取css文件:return:"""# 请求返回的textself.text = requests.get(self.url, headers=self.headers).text# 使用xpath取出所有link中的链接x = etree.HTML(self.text)css_list = x.xpath('//link/@href')self.css_url = 'https:' + str(re.findall('//s3plus\.meituan\.net.+?\.css', ' '.join(css_list))[0])

4.继续分析我们需要的东西

打开这个css文件 发现上一个页面加密的字体的类 在这个css文件中可以用查找到 后面有对应的坐标

5.尝试在css中找寻字体文件

查询css文件中 有没有我们想要的字体文件 command + f 或者 ctrl
+f 查询 发现文件中有三个字体文件 分别打开三个文件的url 发现只有一个字体映射文件是正确的

6.找出正确的字体文件

打开三个字体文件的url 发现正确的就是最多的 也就是最大的一个文件 我们不能凭着url来判断哪个字体文件更大 所以要访问 根据返回的数据 来判断正确的文件是哪个 接下来就要访问url来获取字体文件的内容 然后将最大的字体文件内容存储起来 方便替换

    def down_svg(self):"""下载字体文件:return:"""# css请求返回的textself.css_content = requests.get(self.css_url, headers=self.headers).text# 使用正则取出svg_list = re.findall(r"background-image: url\((.+?)\);", self.css_content)svg_url = ["https:{}".format(svg) for svg in svg_list]# 下载最大的svg文件length_d_l = list()[length_d_l.append({"len": len(requests.get(svg).text), "content": requests.get(svg).text}) for svg in svg_url]self.svg_content = str([x["content"] for x in length_d_l if x["len"] == max([i["len"] for i in length_d_l])][0])

7.由于是动态刷新 将网页数据保存到本地并分析 找到(x,y)和字体的映射关系

取出字体文件后可以在本地进行手动的查询 摸索文字对应关系 因为大众点评每一次刷新都是动态更改css或者svg文件内容 包括每次刷新加密的字都不同 所以将一个保存到本地 根据本地这一个固定的来尝试 尝试成功后动态获取 经过多次尝试 发现规律 两个数字第一个数字除以14
就是文字的下标
此图数字为-406 除以 14 下标 就是29 第二个数字就在两个y值中间 根据规律 匹配出所有文字的映射关系

!!!此段代码只是为了保存数据方便分析和爬取数据的代码无关 !!!

        with open("xx.html", "w")as f:f.write(self.text)with open('xx.css', "w") as f:f.write(self.css_content)with open("font.svg", "w") as f:f.write(self.svg_content)

8.根据找到的规律 取出字体文件中所有字体 还有位置 存储到字典中

用正则在字体文件中取出数字的x值(即在本行的下标)y值用一个元组来存储 判断时 获取加密文字的坐标y值是否在元组两个值中间即可
取出所有的数据 保存到类中的字典
代码实现:

    def font_mapping(self):"""字体映射:return:"""# 使用正则取出字font_list = re.findall(r'<text x=".*" y="(.*)">(.+?)</text>', self.svg_content)# 循环并将映射添加到列表中for num, i in enumerate(font_list):for x, v in enumerate(i[1]):self.font_d_l.append({"value": v,"x": x,"y": (int(font_list[num - 1][0]) if font_list[num - 1][0] != '2495' else 0, int(i[0]))})

存储后的字典格式为 value值为字体内容 x为下标 y值为一个元组 用来存储在哪两个数字之间

9.现在开始获取所有css文件中的类对应的坐标

依旧使用正则来取出所有的数据 查询到的数据 再存储到类中的一个字典
代码实现:

    def position_mapping(self):'''位置映射:return:'''all_ = re.findall("\.(.+?){background:-(.+?)\.0px -(.+?)\.0px;}", self.css_content)[self.position_l.append({"class": i[0],"x": i[1],"y": i[2],}) for i in all_]

字典的格式为:

10.取出所有加密的字

现在取出网页中被加密的字体的class属性 使用xpath取出就可以
代码实现:

    def all_font_position(self):"""所有字体位置:return:"""x = etree.HTML(self.text)self.position_list = x.xpath('//svgmtsi/@class')

11.解密文字

因为现在已经取出了两个字典 一个有加密字体的class属性还有字体的x,y的值 另一个字典中有这个加密字体对应的文字 刚刚我们也取出来所有被加密文字的class属性 只需要循环判断 取出对应的字就可以来
代码实现:

    def find_font(self, x, y):'''查询具体字体:param x::param y::return:'''# 根据坐标返回对应的字体new_x = int(x) / 14for i in self.font_d_l:if int(i.get("x")) == int(new_x) and i.get('y')[0] < int(y) < i.get('y')[1]:return i.get('value')

12.替换所有加密文字为解密后文字

将原来保存的这个网页的text内容中加密的文字 替换为正常的文字
代码实现:
这段代码在最后的运行方法中 就是主方法中

        str_text = str(self.text)for position in self.position_list:for x in self.position_l:if x.get("class") == position:str_text = str_text.replace('<svgmtsi class="{}"></svgmtsi>'.format(position),str(self.find_font(x.get('x'), x.get('y')))).replace("
",'').replace(" ", '')

13.获取数据

最难的加密已经弄出来了 现在就是一个简单的取数据就可以了 因为大众点评的长评论和短评论存储的xpath不同 所以需要一个小判断 直接看代码吧
代码实现:

  def get_data(self, str_text):x = etree.HTML(str_text)# 取出所以li标签li = x.xpath('//div[@class="reviews-items"]/ul/li')print(len(li))for l in li:# 定义一个字典用来存储数据item = dict()# 口味评分flavor = l.xpath("./div/div/span/span[1]/text()")# 环境评分ambient = l.xpath("./div/div/span/span[2]/text()")# 服务评分service = l.xpath("./div/div/span/span[3]/text()")# 人均价格price = l.xpath("./div/div/span/span[4]/text()")# 发布时间times = l.xpath("./div[@class='main-review']/div/span[@class='time']/text()")# 短评论s_comment = l.xpath("div[@class='main-review']/div[@class='review-words']")# 长评论l_comment = l.xpath("div[@class='main-review']//div[@class='review-words Hide']")# 存储到字典中item["flavor"] = str(flavor[0]).replace('\n', '').replace(' ', '') if flavor else "暂无"item["ambient"] = str(ambient[0]).replace('\n', '').replace(' ', '') if ambient else "暂无"item["service"] = str(service[0]).replace('\n', '').replace(' ', '') if service else "暂无"item["price"] = str(price[0]).replace('\n', '').replace(' ', '') if price else "暂无"item["time"] = str(times[0]).replace('\n', '').replace(' ', '') if times else "暂无"# 判断此条评论为长评还是短评 然后存储到字典if l_comment:l_str = html.unescape((etree.tostring(l_comment[0]).decode()))l_com = re.findall('<div class="review-words Hide">(.+?)<div class="less-words">', l_str,re.DOTALL)[0]item["comment"] = l_com.replace('\n', '').replace(' ', '').replace('\t', '')elif s_comment:s_str = html.unescape((etree.tostring(s_comment[0]).decode()))s_com = re.findall('<div class="review-words">(.+?)</div>', s_str, re.DOTALL)[0]item["comment"] = s_com.replace('\n', '').replace(' ', '').replace('\t', '')else:item["comment"] = "该用户没有填写评论..."# 类中的列表 来存储保存后的字典self.data.append(item)

14.保存数据到csv文件中

代码实现:

    def save(self):"""保存数据为csv文件:return:"""pandas.DataFrame(self.data,columns=["flavor", "ambient", "service", "price", "time", "comment"]).to_csv('data.csv')

15.写一个调用所有方法的主方法

代码实现:

    def run(self, url):self.url = url# 获取cssself.down_css()# 获取字体文件self.down_svg()# 添加字体映射self.font_mapping()# 添加位置映射self.position_mapping()# 获取所有加密字体位置self.all_font_position()# 查询对应字体 并替换str_text = str(self.text)for position in self.position_list:for x in self.position_l:if x.get("class") == position:str_text = str_text.replace('<svgmtsi class="{}"></svgmtsi>'.format(position),str(self.find_font(x.get('x'),x.get('y')))).replace("
",'').replace(" ", '')# 获取数据self.get_data(str_text)# 保存文件self.save()# 控制台打印数据pprint(self.data)

16.运行代码

代码如下:

def main():# 创建爬虫对象down_spider = DownComment()# 爬取5页数据for i in range(1, 2):print('-----------当前为{}页---------------'.format(i))url = "http://www.dianping.com/shop/k9oYRvTyiMk4HEdQ/review_all/p{}".format(i)down_spider.run(url=url)

17.查看数据 保存数据

运行代码 查看数据即可 控制台打印以及保存到本地的csv文件 感谢你的观看 希望对你有所帮助
注:网站的反扒策略一直在变 有可能一小时前可以 有可能一小时后就不能使用了

python爬虫实战---爬取大众点评评论相关推荐

  1. python+requests+beautifulsoup爬取大众点评评论信息

    特别声明,此文写于2018年2月,大众点评的页面逻辑,已做了改动,请找最近爬的文章看下,谢谢支持. 先简单聊两句,距离上一篇博客大概过去了4个月,在忙一些别的事情,除了公司有新项目上线,学习新技术之外 ...

  2. Python爬虫实战爬取租房网站2w+数据-链家上海区域信息(超详细)

    Python爬虫实战爬取租房网站-链家上海区域信息(过程超详细) 内容可能有点啰嗦 大佬们请见谅 后面会贴代码 带火们有需求的话就用吧 正好这几天做的实验报告就直接拿过来了,我想后面应该会有人用的到吧 ...

  3. python爬虫实战-爬取视频网站下载视频至本地(selenium)

    #python爬虫实战-爬取视频网站下载视频至本地(selenium) import requests from lxml import etree import json from selenium ...

  4. python爬虫实战-爬取微信公众号所有历史文章 - (00) 概述

    http://efonfighting.imwork.net 欢迎关注微信公众号"一番码客"获取免费下载服务与源码,并及时接收最新文章推送. 最近几年随着人工智能和大数据的兴起,p ...

  5. 反反爬虫之--爬取大众点评--店铺名称、详址、经纬度、评价人数、平均消费等信息

    every blog every motto: Let's be loyal to our ideals, let's face reality-Chegwara 前言: 知难不难! 折腾了几天爬取大 ...

  6. python爬虫实战--爬取猫眼专业版-实时票房

    小白级别的爬虫入门 最近闲来无事,发现了猫眼专业版-实时票房,可以看到在猫眼上映电影的票房数据,便验证自己之前学的python爬虫,爬取数据,做成.svg文件. 爬虫开始之前 我们先来看看猫眼专业版- ...

  7. python爬取大众点评评论_python爬虫抓取数据 小试Python——爬虫抓取大众点评上的数据 - 电脑常识 - 服务器之家...

    python爬虫抓取数据 小试Python--爬虫抓取大众点评上的数据 发布时间:2017-04-07

  8. Python爬虫——selenium爬取网易云评论并做词云

    大家好!我是霖hero 到点了上号网易云,很多人喜欢到夜深人静的时候,在网易云听音乐发表评论,正所谓:自古评论出人才,千古绝句随口来,奈何本人没文化,一句卧槽行天下!评论区集结各路大神,今天我们来爬取 ...

  9. 利用Python爬虫技术爬取京东商品评论

    这是我第一次接触python时,我们学校做的项目实训,其实整个项目实训过程很简单,并没有什么难度,认真学学就会. 首先,我们要明确我们的目标:从京东上爬取产品的评论.一般评论都是进行情感分析,但我还没 ...

最新文章

  1. Fedora9建立交叉编译环境
  2. 解决ubuntu 远程连接问题
  3. OpenGL 开发环境配置
  4. 架构的“一小步”,业务的一大步 1
  5. ubuntu中提示找到make命令的解决方案
  6. 第6章 if命令讲解
  7. jQuery EasyUI使用教程之在数据网格中添加搜索功能
  8. Google搜索技巧终极收集 - 101个Google技巧
  9. 高反差保留滤镜学习OpenCV:滤镜系列(11)——高反差保留
  10. Java中什么是句柄
  11. 如何设置局域网共享打印机及问题解决
  12. 人生没有退路,你所有遇到过的人,做过的事都不是偶然,一念天堂一念地狱
  13. 使用netron对mnist网络结构分析
  14. 网络抖动、丢音、卡顿
  15. hosts—20111010
  16. 高可用和热备份是什么意思?
  17. 使用CDN后网页无法访问怎么解决
  18. 设计模式01---设计模式基础篇01
  19. ios极光推送 App收到推送消息时,修改BadgeNumber,同时点击状态栏消息以后跳到指定的页面和静默推送
  20. 计算机专业大二寒假还没入门,关于考研的入门问题我是一个大二的

热门文章

  1. 深爱的妻子出轨(转贴)
  2. RESTORE 还原数据库
  3. 2021-03-31
  4. 国医中药,人参神秘而又独特的地位
  5. 高人、天才、牛逼…从柳传志到雷军、马云,几乎没人不服任正非!
  6. Office-页码全为0的原因及解决方法
  7. Ext.Window
  8. 遍历当前目录删除指定的文件夹——批处理
  9. html/CSS 字体样式表 font-family:中文字体的英文名称
  10. huyuhang-python-day03