《狄仁杰之四大天王》影評分析(爬蟲+詞云+熱力圖)
作為徐老怪的忠實影迷,《狄仁杰之四大天王》肯定是要去看的,看豆瓣評分和前兩部相差不多,但其實胡蘿卜醬并不是很喜歡前兩部,所以在猶豫要不要去看,受到糖甜甜甜的《我不是藥神》推送影響,于是也簡單去分析了一下《狄仁杰》的影評。
01 數(shù)據(jù)爬取
本來小編是打算爬取豆瓣的全部影評,但是很不幸,數(shù)據(jù)爬取到一半,我的賬號被封了(建議大家改為動態(tài)IP進行爬取,代碼可用,可加QQ群獲取),于是轉(zhuǎn)戰(zhàn)于貓眼。貓眼的短評不能直接通過源碼獲得,需要尋找他的數(shù)據(jù)接口,如下:
http://m.maoyan.com/mmdb/comments/movie/341516.json?_v_=yes&offset=1
其中341516屬于電影的專屬id,offset代表頁數(shù)且只展示1000頁的內(nèi)容,同時僅限于當(dāng)日的評論。此文只為做影評分析演示,所以小編只爬取了今日的評論,去重后僅為幾百條,建議大家多爬取今天的數(shù)據(jù),在做分析。
代碼如下:
- import requests
- import json
- import time
- import random
- #下載一頁數(shù)據(jù)
- def get_one_page(url):
- headers = {
- 'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36'
- }
- response = requests.get(url,headers=headers)
- if response.status_code == 200: #頁面正常響應(yīng)
- return response.text # 返回頁面源代碼
- return None
- #解析一頁數(shù)據(jù)
- def parse_ono_page(html):
- data = json.loads(html)['cmts'] #評論以json形式存儲,故以json形式截取
- for item in data:
- yield{ #該方法返回一個字典
- 'comment':item['content'],
- 'date':item['time'].split(' ')[0],
- 'rate':item['score'],
- 'city':item['cityName'],
- 'nickname':item['nickName']
- }
- #保存數(shù)據(jù)到文本文檔
- def save_to_txt():
- for i in range(1, 1001):
- url='http://m.maoyan.com/mmdb/comments/movie/341516.json?_v_=yes&offset=' + str(i)
- html = get_one_page(url)
- print('正在保存第%d頁.'% i)
- for item in parse_ono_page(html):
- with open('狄仁杰.txt','a',encoding='utf-8') as f:
- f.write(item['date'] + ',' + item['nickname'] + ',' + item['city'] + ',' +str(item['rate'])+','+item['comment']+'\n')
- #反爬
- time.sleep(5 + float(random.randint(1,100)) /20)
- # 獲取的評論可能有重復(fù),為了最終統(tǒng)計的真實性,需做去重處理
- def delete_repeat(old,new):
- oldfile = open(old,'r',encoding='UTF-8')
- newfile = open(new,'w',encoding='UTF-8')
- content_list = oldfile.readlines() #讀取的數(shù)據(jù)集
- content_alreadly_ditinct = [] #存儲不重復(fù)的評論數(shù)據(jù)
- for line in content_list:
- if line not in content_alreadly_ditinct: #評論不重復(fù)
- newfile.write(line+'\n')
- content_alreadly_ditinct.append(line)
- if __name__ =='__main__':
- save_to_txt()
- delete_repeat(r'狄仁杰.txt', r'狄仁杰_new.txt')
爬取數(shù)據(jù)如下:
02 數(shù)據(jù)分析
直觀來看,有用的數(shù)據(jù)僅為城市,評分和評論。我們分別采用熱力圖,柱狀圖和云圖來進行可視化分析。
觀影者分布熱力圖
根據(jù)觀影者的城市,我們畫出了觀影者分布情況,如下圖:
可明顯發(fā)現(xiàn)東部地區(qū),尤其是北京、上海、廣東,成都等城市更為突出,當(dāng)然,這和經(jīng)濟發(fā)展有著重要的聯(lián)系,也符合我們的常規(guī)想法。
代碼如下:
- from wordcloud import WordCloud, STOPWORDS
- import pandas as pd
- import jieba
- import matplotlib.pyplot as plt
- import seaborn as sns
- from pyecharts import Geo
- f = open('狄仁杰_new.txt',encoding='UTF-8')
- data = pd.read_csv(f,sep=',',header=None,encoding='UTF-8',names=['date','nickname','city','rate','comment'])
- city = data.groupby(['city'])
- rate_group = city['rate']
- city_com = city['city'].agg(['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("狄仁杰",title_color="#fff",title_pos="center",width=1200,
- height=600,background_color="#404a59")
- while True:
- try:
- attr, val = geo.cast(data_map)
- geo.add("", attr, val, visual_range=[0, 50], visual_text_color="#fff", is_geo_effect_show=False,
- is_piecewise=True, visual_split_number=6, symbol_size=15, is_visualmap=True)
- except ValueError as e:
- e = str(e)
- e = e.split("No coordinate is specified for ")[1] # 獲取不支持的城市名稱
- for i in range(0,len(data_map)):
- if e in data_map[i]:
- data_map.pop(i)
- break
- else:
- break
- geo.render('狄仁杰.html')
評分柱狀圖
相較于豆瓣的評分機制,在貓眼的評分機制允許給出半星的評價,于是通過簡單的柱狀圖來大概看一下評分情況。
大部分的評分都高于3分,尤其是給出滿分的最多,只有少數(shù)的觀影者給出了低分,看來徐克這部電影的口碑還行,至少在及格線以上。那大家觀完影,最直觀的感受是什么呢,接下來就通過短評分析來看看。
代碼如下:
- #評分分析
- rate = data['rate'].value_counts()
- sns.set_style("darkgrid")
- bar_plot = sns.barplot(x=rate.index,y=(rate.values/sum(rate)),palette="muted")
- plt.xticks(rotation=90)
- plt.show()
短評詞云圖
為了分析短評,我們采用jieba對短評進行了分詞,然后做出詞云圖。
背景圖:
詞云圖:
和前兩部一樣,最突出的是特效,劇情和徐老怪,看來在這部電影里面,徐克肯定也將特效做的很棒,個人風(fēng)格也肯定展示的***。同時,也能發(fā)現(xiàn)好看,不錯,推薦也是觀影者的主要感受,看來還是蠻值得去看的。
代碼如下:
- #分詞
- comment = jieba.cut(str(data["comment"]),cut_all=False)
- wl_space_split= " ".join(comment)
- #導(dǎo)入背景圖
- backgroud_Image = plt.imread('xuke.jpg')
- stopwords = STOPWORDS.copy()
- print(" STOPWORDS.copy()",help(STOPWORDS.copy()))
- #可以自行加多個屏蔽詞,也可直接下載停用詞表格
- stopwords.add("電影")
- stopwords.add("一部")
- stopwords.add("一個")
- stopwords.add("沒有")
- stopwords.add("什么")
- stopwords.add("有點")
- stopwords.add("這部")
- stopwords.add("這個")
- stopwords.add("不是")
- stopwords.add("真的")
- stopwords.add("感覺")
- stopwords.add("覺得")
- stopwords.add("還是")
- stopwords.add("特別")
- stopwords.add("非常")
- stopwords.add("可以")
- stopwords.add("因為")
- stopwords.add("為了")
- stopwords.add("比較")
- print (stopwords)
- #設(shè)置詞云參數(shù)
- #參數(shù)分別是指定字體/背景顏色/***的詞的大小,使用給定圖作為背景形狀
- wc =WordCloud(width=1024,height=768,background_color='white',
- mask = backgroud_Image,font_path='C:/Windows/Fonts/simkai.ttf',
- stopwords=stopwords,max_font_size=400,
- random_state=50)
- #將分詞后數(shù)據(jù)傳入云圖
- wc.generate_from_text(wl_space_split)
- plt.imshow(wc)
- plt.axis('off')#不顯示坐標(biāo)軸
- plt.show()
- #保存結(jié)果到本地
- wc.to_file(r'xuke_wordcloud.jpg')
03 結(jié)語
本文只是做了簡單的數(shù)據(jù)爬取和分析,主要是用以學(xué)習(xí)如何進行分詞,詞云和熱力圖,建議大家可以基于此進行練習(xí)。(胡蘿卜醬要抽空去看狄仁杰了,開熏)