5 多数据save_[Python] 通过采集两万条数据,对无名之辈影评分析
点击上方“Python技术之巅”,马上关注
真爱,请置顶或星标
一、说明
本文主要讲述采集猫眼电影用户评论进行分析,相关爬虫采集程序可以爬取多个电影评论。
运行环境:Win10/Python3.5。
分析工具:jieba、wordcloud、pyecharts、matplotlib。
基本流程:下载内容 ---> 分析获取关键数据 ---> 保存本地文件 ---> 分析本地文件制作图表
注意:本文所有图文和源码仅供学习,请勿他用,转发请注明出处!
本文主要参考:https://mp.weixin.qq.com/s/mTxxkwRZPgBiKC3Sv-jo3g
二、开始采集
2.1、分析数据接口:
为了健全数据样本,数据直接从移动端接口进行采集,连接如下,其中橙色部分为猫眼电影ID,修改即可爬取其他电影。
链接地址:http://m.maoyan.com/mmdb/comments/movie/1208282.json?v=yes&offset=15&startTime=
接口返回的数据如下,主要采集(昵称、城市、评论、评分和时间),用户评论在 json['cmts'] 中:
2.2、爬虫程序核心内容(详细可以看后面源代码):
>启动脚本需要的参数如下(脚本名+猫眼电影ID+上映日期+数据保存的文件名):.\myMovieComment.py 1208282 2016-11-16 myCmts2.txt
>下载html内容:download(self, url),通过python的requests模块进行下载,将下载的数据转成json格式
1 def download(self, url): 2 """下载html内容""" 3 4 print("正在下载URL: "+url) 5 # 下载html内容 6 response = requests.get(url, headers=self.headers) 7 8 # 转成json格式数据 9 if response.status_code == 200:10 return response.json()11 else:12 # print(html.status_code)13 print('下载数据为空!')14 return ""
>然后就是对已下载的内容进行分析,就是取出我们需要的数据:
1 def parse(self, content): 2 """分析数据""" 3 4 comments = [] 5 try: 6 for item in content['cmts']: 7 comment = { 8 'nickName': item['nickName'], # 昵称 9 'cityName': item['cityName'], # 城市10 'content': item['content'], # 评论内容11 'score': item['score'], # 评分12 'startTime': item['startTime'], # 时间13 }14 comments.append(comment)15 16 except Exception as e:17 print(e)18 19 finally:20 return comments
>将分析出来的数据,进行本地保存,方便后续的分析工作:
1 def save(self, data):2 """写入文件"""3 4 print("保存数据,写入文件中...")5 self.save_file.write(data)
> 爬虫的核心控制也即爬虫的程序启动入口,管理上面几个方法的有序执行:
1 def start(self): 2 """启动控制方法""" 3 4 print("爬虫开始...\r\n") 5 6 start_time = self.start_time 7 end_time = self.end_time 8 9 num = 110 while start_time > end_time:11 print("执行次数:", num)12 # 1、下载html13 content = self.download(self.target_url + str(start_time))14 15 # 2、分析获取关键数据16 comments = ''17 if content != "":18 comments = self.parse(content)19 20 if len(comments) <= 0:21 print("本次数据量为:0,退出爬取!\r\n")22 break23 24 # 3、写入文件25 res = ''26 for cmt in comments:27 res += "%s###%s###%s###%s###%s\n" % (cmt['nickName'], cmt['cityName'], cmt['content'], cmt['score'], cmt['startTime'])28 self.save(res)29 30 print("本次数据量:%s\r\n" % len(comments))31 32 # 获取最后一条数据的时间 ,然后减去一秒33 start_time = datetime.strptime(comments[len(comments) - 1]['startTime'], "%Y-%m-%d %H:%M:%S") + timedelta(seconds=-1)34 # start_time = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")35 36 # 休眠3s37 num += 138 time.sleep(3)39 40 self.save_file.close()41 print("爬虫结束...")
2.3 数据样本,最终爬取将近2万条数据,每条记录的每个数据使用 ### 进行分割:
三、图形化分析数据
3.1、制作观众城市分布热点图,(pyecharts-geo):
从图表可以轻松看出,用户主要分布地区,主要以沿海一些发达城市群为主:
1 def createCharts(self): 2 """生成图表""" 3 4 # 读取数据,格式:[{"北京", 10}, {"上海",10}] 5 data = self.readCityNum() 6 7 # 1 热点图 8 geo1 = Geo("《无名之辈》观众位置分布热点图", "数据来源:猫眼,Fly采集", title_color="#FFF", title_pos="center", width="100%", height=600, background_color="#404A59") 9 10 attr1, value1 = geo1.cast(data)11 12 geo1.add("", attr1, value1, type="heatmap", visual_range=[0, 1000], visual_text_color="#FFF", symbol_size=15, is_visualmap=True, is_piecewise=False, visual_split_number=10)13 geo1.render("files/无名之辈-观众位置热点图.html")14 15 # 2 位置图16 geo2 = Geo("《无名之辈》观众位置分布", "数据来源:猫眼,Fly采集", title_color="#FFF", title_pos="center", width="100%", height=600,17 background_color="#404A59")18 19 attr2, value2 = geo1.cast(data)20 geo2.add("", attr2, value2, visual_range=[0, 1000], visual_text_color="#FFF", symbol_size=15,21 is_visualmap=True, is_piecewise=False, visual_split_number=10)22 geo2.render("files/无名之辈-观众位置图.html")23 24 # 3、top20 柱状图25 data_top20 = data[:20]26 bar = Bar("《无名之辈》观众来源排行 TOP20", "数据来源:猫眼,Fly采集", title_pos="center", width="100%", height=600)27 attr, value = bar.cast(data_top20)28 bar.add('', attr, value, is_visualmap=True, visual_range=[0, 3500], visual_text_color="#FFF", is_more_utils=True, is_label_show=True)29 bar.render("files/无名之辈-观众来源top20.html")30 31 print("图表生成完成")
3.2、制作观众人数TOP20的柱形图,(pyecharts-bar):
3.3、制作评论词云,(jieba、wordcloud):
生成词云核心代码:
1 def createWordCloud(self): 2 """生成评论词云""" 3 comments = self.readAllComments() # 19185 4 5 # 使用 jieba 分词 6 commens_split = jieba.cut(str(comments), cut_all=False) 7 words = ''.join(commens_split) 8 9 # 给词库添加停止词10 stopwords = STOPWORDS.copy()11 stopwords.add("电影")12 stopwords.add("一部")13 stopwords.add("无名之辈")14 stopwords.add("一部")15 stopwords.add("一个")16 stopwords.add("有点")17 stopwords.add("觉得")18 19 # 加载背景图片20 bg_image = plt.imread("files/2048_bg.png")21 22 # 初始化 WordCloud23 wc = WordCloud(width=1200, height=600, background_color='#FFF', mask=bg_image, font_path='C:/Windows/Fonts/STFANGSO.ttf', stopwords=stopwords, max_font_size=400, random_state=50)24 25 # 生成,显示图片26 wc.generate_from_text(words)27 plt.imshow(wc)28 plt.axis('off')29 plt.show()
四、修改pyecharts源码
4.1、样本数据的城市简称与数据集完整城市名匹配不上:
使用位置热点图时候,由于采集数据城市是一些简称,与pyecharts的已存在数据的城市名对不上, 所以对源码进行一些修改,方便匹配一些简称。
黔南 => 黔南布依族苗族自治州
模块自带的全国主要市县经纬度在:[python安装路径]\Lib\site-packages\pyecharts\datasets\city_coordinates.json
由于默认情况下,一旦城市名不能完全匹配就会报异常,程序会停止,所以对源码修改如下(报错方法为 Geo.add()),其中添加注析为个人修改部分:
1 def get_coordinate(self, name, region="中国", raise_exception=False): 2 """ 3 Return coordinate for the city name. 4 5 :param name: City name or any custom name string. 6 :param raise_exception: Whether to raise exception if not exist. 7 :return: A list like [longitude, latitude] or None 8 """ 9 if name in self._coordinates:10 return self._coordinates[name]11 12 13 coordinate = get_coordinate(name, region=region)14 15 # [ 20181204 添加16 # print(name, coordinate)17 if coordinate is None:18 # 如果字典key匹配不上,尝试进行模糊查询19 search_res = search_coordinates_by_region_and_keyword(region, name)20 # print("###",search_res)21 if search_res:22 coordinate = sorted(search_res.values())[0]23 # 20181204 添加 ]24 25 if coordinate is None and raise_exception:26 raise ValueError("No coordinate is specified for {}".format(name))27 28 return coordinate
相应的需要对 __add()方法进行如下修改:
五、附录-源码
5.1 采集源码
1 # -*- coding:utf-8 -*- 2 3 import requests 4 from datetime import datetime, timedelta 5 import os 6 import time 7 import sys 8 9 10 class MaoyanFilmReviewSpider: 11 """猫眼影评爬虫""" 12 13 def __init__(self, url, end_time, filename): 14 # 头部 15 self.headers = { 16 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1' 17 } 18 19 # 目标URL 20 self.target_url = url 21 22 # 数据获取时间段,start_time:截止日期,end_time:上映时间 23 now = datetime.now() 24 25 # 获取当天的 零点 26 self.start_time = now + timedelta(hours=-now.hour, minutes=-now.minute, seconds=-now.second) 27 self.start_time = self.start_time.replace(microsecond=0) 28 self.end_time = datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S") 29 30 # 打开写入文件, 创建目录 31 self.save_path = "files/" 32 if not os.path.exists(self.save_path): 33 os.makedirs(self.save_path) 34 self.save_file = open(self.save_path + filename, "a", encoding="utf-8") 35 36 def download(self, url): 37 """下载html内容""" 38 39 print("正在下载URL: "+url) 40 # 下载html内容 41 response = requests.get(url, headers=self.headers) 42 43 # 转成json格式数据 44 if response.status_code == 200: 45 return response.json() 46 else: 47 # print(html.status_code) 48 print('下载数据为空!') 49 return "" 50 51 def parse(self, content): 52 """分析数据""" 53 54 comments = [] 55 try: 56 for item in content['cmts']: 57 comment = { 58 'nickName': item['nickName'], # 昵称 59 'cityName': item['cityName'], # 城市 60 'content': item['content'], # 评论内容 61 'score': item['score'], # 评分 62 'startTime': item['startTime'], # 时间 63 } 64 comments.append(comment) 65 66 except Exception as e: 67 print(e) 68 69 finally: 70 return comments 71 72 def save(self, data): 73 """写入文件""" 74 75 print("保存数据,写入文件中...") 76 self.save_file.write(data) 77 78 def start(self): 79 """启动控制方法""" 80 81 print("爬虫开始...\r\n") 82 83 start_time = self.start_time 84 end_time = self.end_time 85 86 num = 1 87 while start_time > end_time: 88 print("执行次数:", num) 89 # 1、下载html 90 content = self.download(self.target_url + str(start_time)) 91 92 # 2、分析获取关键数据 93 comments = '' 94 if content != "": 95 comments = self.parse(content) 96 97 if len(comments) <= 0: 98 print("本次数据量为:0,退出爬取!\r\n") 99 break100 101 # 3、写入文件102 res = ''103 for cmt in comments:104 res += "%s###%s###%s###%s###%s\n" % (cmt['nickName'], cmt['cityName'], cmt['content'], cmt['score'], cmt['startTime'])105 self.save(res)106 107 print("本次数据量:%s\r\n" % len(comments))108 109 # 获取最后一条数据的时间 ,然后减去一秒110 start_time = datetime.strptime(comments[len(comments) - 1]['startTime'], "%Y-%m-%d %H:%M:%S") + timedelta(seconds=-1)111 # start_time = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")112 113 # 休眠3s114 num += 1115 time.sleep(3)116 117 self.save_file.close()118 print("爬虫结束...")119 120 121 if __name__ == "__main__":122 # 确保输入参数123 if len(sys.argv) != 4:124 print("请输入相关参数:[moveid]、[上映日期]和[保存文件名],如:xxx.py 42962 2018-11-09 text.txt")125 exit()126 127 # 猫眼电影ID128 mid = sys.argv[1] # "1208282" # "42964"129 # 电影上映日期130 end_time = sys.argv[2] # "2018-11-16" # "2018-11-09"131 # 每次爬取条数132 offset = 15133 # 保存文件名134 filename = sys.argv[3]135 136 spider = MaoyanFilmReviewSpider(url="http://m.maoyan.com/mmdb/comments/movie/%s.json?v=yes&offset=%d&startTime=" % (mid, offset), end_time="%s 00:00:00" % end_time, filename=filename)137 # spider.start()138 139 spider.start()140 # t1 = "2018-11-09 23:56:23"141 # t2 = "2018-11-25"142 #143 # res = datetime.strptime(t1, "%Y-%m-%d %H:%M:%S") + timedelta(days=-1)144 # print(type(res))
5.2 分析制图源码
1 # -*- coding:utf-8 -*- 2 from pyecharts import Geo, Bar, Bar3D 3 import jieba 4 from wordcloud import STOPWORDS, WordCloud 5 import matplotlib.pyplot as plt 6 7 8 class ACoolFishAnalysis: 9 """无名之辈 --- 数据分析""" 10 def __init__(self): 11 pass 12 13 def readCityNum(self): 14 """读取观众城市分布数量""" 15 d = {} 16 17 with open("files/myCmts2.txt", "r", encoding="utf-8") as f: 18 row = f.readline() 19 20 while row != "": 21 arr = row.split('###') 22 23 # 确保每条记录长度为 5 24 while len(arr) 5: 25 row += f.readline() 26 arr = row.split('###') 27 28 # 记录每个城市的人数 29 if arr[1] in d: 30 d[arr[1]] += 1 31 else: 32 d[arr[1]] = 1 # 首次加入字典,为 1 33 34 row = f.readline() 35 36 37 # print(len(comments)) 38 # print(d) 39 40 # 字典 转 元组数组 41 res = [] 42 for ks in d.keys(): 43 if ks == "": 44 continue 45 tmp = (ks, d[ks]) 46 res.append(tmp) 47 48 # 按地点人数降序 49 res = sorted(res, key=lambda x: (x[1]),reverse=True) 50 return res 51 52 def readAllComments(self): 53 """读取所有评论""" 54 comments = [] 55 56 # 打开文件读取数据 57 with open("files/myCmts2.txt", "r", encoding="utf-8") as f: 58 row = f.readline() 59 60 while row != "": 61 arr = row.split('###') 62 63 # 每天记录长度为 5 64 while len(arr) 5: 65 row += f.readline() 66 arr = row.split('###') 67 68 if len(arr) == 5: 69 comments.append(arr[2]) 70 71 # if len(comments) > 20: 72 # break 73 row = f.readline() 74 75 return comments 76 77 def createCharts(self): 78 """生成图表""" 79 80 # 读取数据,格式:[{"北京", 10}, {"上海",10}] 81 data = self.readCityNum() 82 83 # 1 热点图 84 geo1 = Geo("《无名之辈》观众位置分布热点图", "数据来源:猫眼,Fly采集", title_color="#FFF", title_pos="center", width="100%", height=600, background_color="#404A59") 85 86 attr1, value1 = geo1.cast(data) 87 88 geo1.add("", attr1, value1, type="heatmap", visual_range=[0, 1000], visual_text_color="#FFF", symbol_size=15, is_visualmap=True, is_piecewise=False, visual_split_number=10) 89 geo1.render("files/无名之辈-观众位置热点图.html") 90 91 # 2 位置图 92 geo2 = Geo("《无名之辈》观众位置分布", "数据来源:猫眼,Fly采集", title_color="#FFF", title_pos="center", width="100%", height=600, 93 background_color="#404A59") 94 95 attr2, value2 = geo1.cast(data) 96 geo2.add("", attr2, value2, visual_range=[0, 1000], visual_text_color="#FFF", symbol_size=15, 97 is_visualmap=True, is_piecewise=False, visual_split_number=10) 98 geo2.render("files/无名之辈-观众位置图.html") 99 100 # 3、top20 柱状图101 data_top20 = data[:20]102 bar = Bar("《无名之辈》观众来源排行 TOP20", "数据来源:猫眼,Fly采集", title_pos="center", width="100%", height=600)103 attr, value = bar.cast(data_top20)104 bar.add('', attr, value, is_visualmap=True, visual_range=[0, 3500], visual_text_color="#FFF", is_more_utils=True, is_label_show=True)105 bar.render("files/无名之辈-观众来源top20.html")106 107 print("图表生成完成")108 109 def createWordCloud(self):110 """生成评论词云"""111 comments = self.readAllComments() # 19185112 113 # 使用 jieba 分词114 commens_split = jieba.cut(str(comments), cut_all=False)115 words = ''.join(commens_split)116 117 # 给词库添加停止词118 stopwords = STOPWORDS.copy()119 stopwords.add("电影")120 stopwords.add("一部")121 stopwords.add("无名之辈")122 stopwords.add("一部")123 stopwords.add("一个")124 stopwords.add("有点")125 stopwords.add("觉得")126 127 # 加载背景图片128 bg_image = plt.imread("files/2048_bg.png")129 130 # 初始化 WordCloud131 wc = WordCloud(width=1200, height=600, background_color='#FFF', mask=bg_image, font_path='C:/Windows/Fonts/STFANGSO.ttf', stopwords=stopwords, max_font_size=400, random_state=50)132 133 # 生成,显示图片134 wc.generate_from_text(words)135 plt.imshow(wc)136 plt.axis('off')137 plt.show()138 139 140 141 if __name__ == "__main__":142 demo = ACoolFishAnalysis()143 demo.createWordCloud()
本文作者:蜗牛噢,原文链接:https://www.cnblogs.com/reader/p/10070629.html
推荐阅读
Python人体肤色检测
【Python】动手分析天猫内衣售卖数据,得到你想知道的信息
python爬虫实战:利用scrapy,短短50行代码下载整站短视频
5 多数据save_[Python] 通过采集两万条数据,对无名之辈影评分析相关推荐
- [Python] 通过采集两万条数据,对《无名之辈》影评分析
一.说明 本文主要讲述采集猫眼电影用户评论进行分析,相关爬虫采集程序可以爬取多个电影评论. 运行环境:Win10/Python3.5. 分析工具:jieba.wordcloud.pyecharts.m ...
- 基于python的影评数据分析_[Python] 通过采集两万条数据,对《无名之辈》影评分析...
一.说明 本文主要讲述采集猫眼电影用户评论进行分析,相关爬虫采集程序可以爬取多个电影评论. 运行环境:Win10/Python3.5. 分析工具:jieba.wordcloud.pyecharts.m ...
- 两万条数据需要做个数据图_第3关:基于Excel对电商母婴数据进行分析
对于新手,拿到数据往往不知如何下手.那就按图索骥,依照以下五部一步步来 step1:明确问题 目标必须明确,基于当前业务出发.如一千个读者有一千个哈姆雷特一样,数据可以被解读出不同样子,必须集中目标, ...
- python多线程插入1万条数据
前言 在业务中,经常碰到需要从外部批量读取数据然后导入到mysql等数据库的操作,通常情况下,我们使用一个insert语句就可以完成,但在数据量为上万甚至百万的时候,这样做是不是太耗时了呢? 下面我们 ...
- 利用python处理两千万条数据的一些经验(仅供自己记录)
5.3老板交给我一个任务,简单处理一些数据,三个CSV文件,每个都是2.3G大小,以下是要求 看着觉得很easy,兴冲冲地去搞了,当时还是用的notepad++写python代码,对于python来说 ...
- 我们用Python分析了B站4万条数据评论,揭秘本山大叔《念诗之王》大热原因!...
来源:恋习Python 本文约2000字,建议阅读10分钟. 我们通过Python大法通过获取B站:[春晚鬼畜]赵本山:我就是念诗之王!4万条数据评论,与大家一起看看其背后火起来的原因. 1990年本 ...
- Python 分析 9 万条数据告诉你复仇者联盟谁才是绝对 C 位!
<复联 4>国内上映第十天,程序员的江湖里开始流传这样一个故事,即: 漫威宇宙,其实就讲了一件事情.整个宇宙就好比一个项目组.其中有一群叫作美国队长.钢铁侠.惊奇队长.浩克.索尔等人在维护 ...
- 爬取网易云音乐两万条评论储存在MySQL服务器上
爬取网易云音乐两万条评论储存在MySQL服务器上 最近在公司实习,无聊时看看别人的博客,发现平时学习写写博客是一个很好的学习方法,报平时一些自己写的代码保存下来,遇到的错误踩到的坑也拿出来分享也可也帮 ...
- Python看春运,万条拼车数据背后的春节迁徙地图
Python看春运,万条拼车数据背后的春节迁徙地图 今天是正月初九,春运返程也已过半.这篇文章,作者对北京.上海.广州.深圳.杭州等地 1万多条出行数据进行分析,得出了一些有意思的结论,并且绘制了这几 ...
最新文章
- android中PreferencesActivity的使用(一)
- T-SQL中的随机数
- block之--- 基本使用
- Cannot open D:\Program Files\Anaconda3\Scripts\pip-script.py 错误解决办法
- 迷你世界电锯机器人_迷你世界:会旋转的机器人,安装多个火箭炮,全方位轰炸敌人...
- linux清理内存命令
- AgileEAS.NET平台应用开发教程-案例计划
- redis通过expire设置存活期注意问题
- 前端笔记-JavaScript中放json数组要注意的地方(构造灵活的echarts)
- poj 1039 Pipe (判断 直线和 线段 是否相交 并 求交点)
- 【AD】PCB设计知识整理(持续更新)
- python代码中怎么增加数据_python 实现数据库中数据添加、查询与更新的示例代码...
- 吴恩达机器学习学习笔记第一章:绪论初识机器学习
- linux下目录简介——/proc
- 携程android app插件化
- 谈谈ILDasm的功能限制与解除
- csdn博客修改名字,不需要重新注册的。
- Excel:INDEX与MATCH函数
- win10打印机无法打印(怎样使用打印机打印)
- 1153: 简易版最长序列 C语言
热门文章
- 瑞幸咖啡 CEO 和 COO 被暂停职务;快手起诉抖音索赔 500 万元;Wine 5.8 发布 | 极客头条...
- 终于有人对语音技术来了次彻头彻尾的批判!
- “手把手撕LeetCode题目,扒各种算法套路的裤子”
- 罗永浩宣布进军电商直播;微博回应用户数据泄露;Android 11 开发者预览版 2 发布 | 极客头条...
- JavaScript 造就年薪超过 10 万美元的开发者们!
- 召唤新一代超参调优开源新神器,集十大主流模块于一身
- 百行代码解读阿里 AloT 芯片平台无剑 100!
- 别样的1024程序员节“无Bug市集”
- 作为新手程序员,掉过的那些坑!
- 阿里 90 后科学家研发,达摩院开源新一代 AI 算法模型