前言

文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者: 罗昭成

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

获取猫眼接口数据

作为一个长期宅在家的程序员,对各种抓包简直是信手拈来。在 Chrome 中查看原代码的模式,可以很清晰地看到接口,接口地址即为:

http://m.maoyan.com/mmdb/comments/movie/1208282.json?_v_=yes&offset=15

在 Python 中,我们可以很方便地使用 request 来发送网络请求,进而拿到返回结果:

 def getMoveinfo(url):
session = requests.Session()
headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X)"
}
response = session.get(url, headers=headers)
if response.status_code == 200:
return response.text
return None

根据上面的请求,我们能拿到此接口的返回数据,数据内容有很多信息,但有很多信息是我们并不需要的,先来总体看看返回的数据:

 {
"cmts":[
{
"approve":0,
"approved":false,
"assistAwardInfo":{
"avatar":"",
"celebrityId":0,
"celebrityName":"",
"rank":0,
"title":""
},
"authInfo":"",
"cityName":"贵阳",
"content":"必须十分,借钱都要看的一部电影。",
"filmView":false,
"id":1045570589,
"isMajor":false,
"juryLevel":0,
"majorType":0,
"movieId":1208282,
"nick":"nick",
"nickName":"nickName",
"oppose":0,
"pro":false,
"reply":0,
"score":5,
"spoiler":0,
"startTime":"2018-11-22 23:52:58",
"supportComment":true,
"supportLike":true,
"sureViewed":1,
"tagList":{
"fixed":[
{
"id":1,
"name":"好评"
},
{
"id":4,
"name":"购票"
}
]
},
"time":"2018-11-22 23:52",
"userId":1871534544,
"userLevel":2,
"videoDuration":0,
"vipInfo":"",
"vipType":0
}
]
}

如此多的数据,我们感兴趣的只有以下这几个字段:

nickName, cityName, content, startTimescore

接下来,进行我们比较重要的数据处理,从拿到的 JSON 数据中解析出需要的字段:

 def parseInfo(data):
data = json.loads(html)['cmts']
for item in data:
yield{
'date':item['startTime'],
'nickname':item['nickName'],
'city':item['cityName'],
'rate':item['score'],
'conment':item['content']
}

拿到数据后,我们就可以开始数据分析了。但是为了避免频繁地去猫眼请求数据,需要将数据存储起来,在这里,笔者使用的是 SQLite3,放到数据库中,更加方便后续的处理。存储数据的代码如下:

 def saveCommentInfo(moveId, nikename, comment, rate, city, start_time)
conn = sqlite3.connect('unknow_name.db')
conn.text_factory=str
cursor = conn.cursor()
ins="insert into comments values (?,?,?,?,?,?)"
v = (moveId, nikename, comment, rate, city, start_time)
cursor.execute(ins,v)
cursor.close()
conn.commit()
conn.close()

数据处理

因为前文我们是使用数据库来进行数据存储的,因此可以直接使用 SQL 来查询自己想要的结果,比如评论前五的城市都有哪些:

SELECT  city, count(*) rate_count  FROM comments GROUP BY city ORDER BY rate_count DESC LIMIT 5

结果如下:

从上面的数据, 我们可以看出来,来自北京的评论数最多。

不仅如此,还可以使用更多的 SQL 语句来查询想要的结果。比如每个评分的人数、所占的比例等。如笔者有兴趣,可以尝试着去查询一下数据,就是如此地简单。

而为了更好地展示数据,我们使用 Pyecharts 这个库来进行数据可视化展示。

根据从猫眼拿到的数据,按照地理位置,直接使用 Pyecharts 来在中国地图上展示数据:

 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
city = data.groupby(['city'])
city_com = city['rate'].agg(['mean','count'])
city_com.reset_index(inplace=True)
data_map = [(city_com['city'][i],city_com['count'][i]) for i in range(0,city_com.shape[0])]
geo = Geo("GEO 地理位置分析",title_pos = "center",width = 1200,height = 800)
while True:
try:
attr,val = geo.cast(data_map)
geo.add("",attr,val,visual_range=[0,300],visual_text_color="#fff",
symbol_size=10, is_visualmap=True,maptype='china')

except ValueError as e:
e = e.message.split("No coordinate is specified for ")[1]
data_map = filter(lambda item: item[0] != e, data_map)
else :
break
geo.render('geo_city_location.html')

注:使用 Pyecharts 提供的数据地图中,有一些猫眼数据中的城市找不到对应的从标,所以在代码中,GEO 添加出错的城市,我们将其直接删除,过滤掉了不少的数据。

使用 Python,就是如此简单地生成了如下地图:

从可视化数据中可以看出,既看电影又评论的人群主要分布在中国东部,又以北京、上海、成都、深圳最多。虽然能从图上看出来很多数据,但还是不够直观,如果想看到每个省/市的分布情况,我们还需要进一步处理数据。

而在从猫眼中拿到的数据中,城市包含数据中具备县城的数据,所以需要将拿到的数据做一次转换,将所有的县城转换到对应省市里去,然后再将同一个省市的评论数量相加,得到最后的结果。

 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
city = data.groupby(['city'])
city_com = city['rate'].agg(['mean','count'])
city_com.reset_index(inplace=True)
fo = open("citys.json",'r')
citys_info = fo.readlines()
citysJson = json.loads(str(citys_info[0]))
data_map_all = [(getRealName(city_com['city'][i], citysJson),city_com['count'][i]) for i in range(0,city_com.shape[0])]
data_map_list = {}
for item in data_map_all:
if data_map_list.has_key(item[0]):
value = data_map_list[item[0]]
value += item[1]
data_map_list[item[0]] = value
else:
data_map_list[item[0]] = item[1]
data_map = [(realKeys(key), data_map_list[key] ) for key in data_map_list.keys()]
def getRealName(name, jsonObj):
for item in jsonObj:
if item.startswith(name) :
return jsonObj[item]
return name
def realKeys(name):
return name.replace(u"省", "").replace(u"市", "")
.replace(u"回族自治区", "").replace(u"维吾尔自治区", "")
.replace(u"壮族自治区", "").replace(u"自治区", "")

经过上面的数据处理,使用 Pyecharts 提供的 map 来生成一个按省/市来展示的地图:

 def generateMap(data_map):
map = Map("城市评论数", width= 1200, height = 800, title_pos="center")
while True:
try:
attr,val = geo.cast(data_map)
map.add("",attr,val,visual_range=[0,800],
visual_text_color="#fff",symbol_size=5,
is_visualmap=True,maptype='china',
is_map_symbol_show=False,is_label_show=True,is_roam=False,
)
except ValueError as e:
e = e.message.split("No coordinate is specified for ")[1]
data_map = filter(lambda item: item[0] != e, data_map)
else :
break
map.render('city_rate_count.html')

当然,我们还可以来可视化一下每一个评分的人数,这个地方采用柱状图来显示:

 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
# 按评分分类
rateData = data.groupby(['rate'])
rateDataCount = rateData["date"].agg([ "count"])
rateDataCount.reset_index(inplace=True)
count = rateDataCount.shape[0] - 1
attr = [rateDataCount["rate"][count - i] for i in range(0, rateDataCount.shape[0])]
v1 = [rateDataCount["count"][count - i] for i in range(0, rateDataCount.shape[0])]
bar = Bar("评分数量")
bar.add("数量",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
xaxis_interval=0,is_splitline_show=True)
bar.render("html/rate_count.html")

画出来的图,如下所示,在猫眼的数据中,五星好评的占比超过了 50%,比豆瓣上 34.8% 的五星数据好很多。

从以上观众分布和评分的数据可以看到,这一部剧,观众朋友还是非常地喜欢。前面,从猫眼拿到了观众的评论数据。现在,笔者将通过 jieba 把评论进行分词,然后通过 Wordcloud 制作词云,来看看,观众朋友们对《无名之辈》的整体评价:

 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
comment = jieba.cut(str(data['comment']),cut_all=False)
wl_space_split = " ".join(comment)
backgroudImage = np.array(Image.open(r"./unknow_3.png"))
stopword = STOPWORDS.copy()
wc = WordCloud(width=1920,height=1080,background_color='white',
mask=backgroudImage,
font_path="./Deng.ttf",
stopwords=stopword,max_font_size=400,
random_state=50)
wc.generate_from_text(wl_space_split)
plt.imshow(wc)
plt.axis("off")
wc.to_file('unknow_word_cloud.png')

导出:

.

Python 爬取猫眼电影《无名之辈》并对其进行数据分析的更多相关文章

  1. 爬虫系列(1)-----python爬取猫眼电影top100榜

    对于Python初学者来说,爬虫技能是应该是最好入门,也是最能够有让自己有成就感的,今天在整理代码时,整理了一下之前自己学习爬虫的一些代码,今天先上一个简单的例子,手把手教你入门Python爬虫,爬取 ...

  2. python 爬取猫眼电影top100数据

    最近有爬虫相关的需求,所以上B站找了个视频(链接在文末)看了一下,做了一个小程序出来,大体上没有修改,只是在最后的存储上,由txt换成了excel. 简要需求:爬虫爬取 猫眼电影TOP100榜单 数据 ...

  3. Python 爬取猫眼电影最受期待榜

     主要爬取猫眼电影最受期待榜的电影排名.图片链接.名称.主演.上映时间. 思路:1.定义一个获取网页源代码的函数: 2.定义一个解析网页源代码的函数: 3.定义一个将解析的数据保存为本地文件的函数: ...

  4. python爬取猫眼电影top100

    最近想研究下python爬虫,于是就找了些练习项目试试手,熟悉一下,猫眼电影可能就是那种最简单的了. 1 看下猫眼电影的top100页面 分了10页,url为:https://maoyan.com/b ...

  5. Python爬取猫眼电影100榜并保存到excel表格

    首先我们前期要导入的第三方类库有; 通过猫眼电影100榜的源码可以看到很有规律 如: 亦或者是: 根据规律我们可以得到非贪婪的正则表达式 """<div class ...

  6. Python爬取猫眼电影《飞驰人生》47858万条评论并对其进行数据分析

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Yura不说数据说 ,PYuraL PS:如有需要Python学习资 ...

  7. Python爬取猫眼电影排行

    import requests import pyquery def crawl_page(url: str) -> None: headers = { 'user-agent': 'Mozil ...

  8. Python使用asyncio+aiohttp异步爬取猫眼电影专业版

    asyncio是从pytohn3.4开始添加到标准库中的一个强大的异步并发库,可以很好地解决python中高并发的问题,入门学习可以参考官方文档 并发访问能极大的提高爬虫的性能,但是requests访 ...

  9. 票房和口碑称霸国庆档,用 Python 爬取猫眼评论区看看电影《我和我的家乡》到底有多牛

    今年的国庆档电影市场的表现还是比较强势的,两名主力<我和我的家乡>和<姜子牙>起到了很好的带头作用. <姜子牙>首日破 2 亿,一举刷新由<哪吒之魔童降世&g ...

随机推荐

  1. IT兄弟连 HTML5教程 CSS3揭秘 在HTML文档中放置CSS的几种方式

    有很多方法将样式表加入到HTML中,每种方法都有自己的优点和缺点.新的HTML元素和属性已被加入,以允许样式表与HTML文档更简易地组合起来.将样式表加入到HTML中的常用方法有内联样式表.嵌入一张样 ...

  2. 【Git教程】如何清除git仓库的所有提交记录,成为一个新的干净仓库

    一.引言 马三也算Github的忠实用户了,经常会把一些练手的项目传到Github上面进行备份.其中有一个名为ColaFramework的Unity框架项目,马三开发了一年多了,期间提交代码的时候在L ...

  3. Swoole 启动一个服务,开启了哪些进程和线程?

    目录 概述 代码 小结 概述 Swoole 启动一个服务,开启了哪些进程和线程? 为了解决这个问题,咱们启动一个最简单的服务,一起看看究竟启动了哪些进程和线程? 然后结合官网运行流程图,对每个进程和线 ...

  4. PlayJava Day014

    今日所学: /* 2019.08.19开始学习,此为补档. */ 1.Random生成的随机数是伪随机数,因为只要两个Random对象的种子相同,而且方法的调用顺序也相同,则产生的随机数相同. Ran ...

  5. 松软科技web课堂:JavaScript 数组方法

    JavaScript 数组的力量隐藏在数组方法中. 把数组转换为字符串 JavaScript 方法 toString() 把数组转换为数组值(逗号分隔)的字符串. 实例 var fruits = [& ...

  6. Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式

    1.Class对象获取的三种方式 本文转载自:https://blog.csdn.net/hanchao5272/article/details/79361463 上一章节已经说过,一般情况下,Jav ...

  7. 简单的jquery表单验证+添加+删除+全选/反选

    //布局 <body> <h4><a href="#">首页</a>><a href="#"> ...

  8. 微信小程序出现 text 设置行高 line-height 无效的问题

    前言: 我在写程序过程中遇到过给text加line-height不生效的问题,但是也有生效的情况,如果不生效了就按下面的解决方法处理吧. 解决办法: 在text的外层嵌套一层view,然后给view设 ...

  9. Linux系统学习 七、网络基础—常用网络命令

    1.ifconfig                 #查看网络(设置IP临时生效) 2.hostname [主机名]            #查看或设置主机名       默认的是localhost ...

  10. JVM GC算法 垃圾回收器

    JVM的垃圾回收算法有三种: 1.标记-清除(mark-sweep):啥都不说,直接上图 2.标记-整理(mark-compact) 3.复制(copy) 分代收集算法                 ...