前言
作者: 罗昭成
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 来发送网络请求,进而拿到返回结果:
1
2
3
4
5
6
7
8
9
|
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
|
根据上面的请求,我们能拿到此接口的返回数据,数据内容有很多信息,但有很多信息是我们并不需要的,先来总体看看返回的数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
{
"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, startTime, score
接下来,进行我们比较重要的数据处理,从拿到的 JSON 数据中解析出需要的字段:
1
2
3
4
5
6
7
8
9
10
|
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,放到数据库中,更加方便后续的处理。存储数据的代码如下:
1
2
3
4
5
6
7
8
9
10
|
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 来查询自己想要的结果,比如评论前五的城市都有哪些:
1
|
SELECT city, count( * ) rate_count FROM comments GROUP BY city ORDER BY rate_count DESC LIMIT 5
|
结果如下:
从上面的数据, 我们可以看出来,来自北京的评论数最多。
不仅如此,还可以使用更多的 SQL 语句来查询想要的结果。比如每个评分的人数、所占的比例等。如笔者有兴趣,可以尝试着去查询一下数据,就是如此地简单。
而为了更好地展示数据,我们使用 Pyecharts 这个库来进行数据可视化展示。
根据从猫眼拿到的数据,按照地理位置,直接使用 Pyecharts 来在中国地图上展示数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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,就是如此简单地生成了如下地图:
从可视化数据中可以看出,既看电影又评论的人群主要分布在中国东部,又以北京、上海、成都、深圳最多。虽然能从图上看出来很多数据,但还是不够直观,如果想看到每个省/市的分布情况,我们还需要进一步处理数据。
而在从猫眼中拿到的数据中,城市包含数据中具备县城的数据,所以需要将拿到的数据做一次转换,将所有的县城转换到对应省市里去,然后再将同一个省市的评论数量相加,得到最后的结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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 来生成一个按省/市来展示的地图:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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' )
|
当然,我们还可以来可视化一下每一个评分的人数,这个地方采用柱状图来显示:
1
2
3
4
5
6
7
8
9
10
11
12
|
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 制作词云,来看看,观众朋友们对《无名之辈》的整体评价:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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 爬取猫眼电影数据分析《无名之辈》的文章就介绍到这了,更多相关Python 爬取猫眼电影数据分析《无名之辈》内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/Qqun821460695/p/11953720.html