中國(guó)人民志愿軍抗美援朝出國(guó)作戰(zhàn)70周年,我用 Python 為英雄們送上祝福

文 |?豆豆
來源:Python 技術(shù)「ID: pythonall」

今年是中國(guó)人民志愿軍抗美援朝出國(guó)作戰(zhàn) 70 周年,剛好上個(gè)月上映了同題材的電影「金剛川」。該影片主要講的是抗美援朝戰(zhàn)爭(zhēng)最終階段,志愿軍準(zhǔn)備在金城發(fā)動(dòng)最后一場(chǎng)大型戰(zhàn)役。為在指定時(shí)間到達(dá),向金城前線投放更多戰(zhàn)力,志愿軍戰(zhàn)士們?cè)谖镔Y匱乏、武器裝備相差懸殊的情況下,不斷抵御敵機(jī)狂轟濫炸,以血肉之軀一次次修補(bǔ)戰(zhàn)火中的木橋。
今天我們就用 Python 來分析一下「金剛川」這部電影,看看網(wǎng)友們對(duì)該劇的評(píng)論如何。
要想分析該劇,首先則需要獲取數(shù)據(jù)源,豆瓣作為國(guó)內(nèi)最大的文藝青年聚居地,其電影影評(píng)評(píng)分一直是比較客觀的,所以這次我們選取豆瓣電影作為數(shù)據(jù)來源。
數(shù)據(jù)獲取

從豆瓣電影我們可以看出,該劇共有十三萬(wàn)多人進(jìn)行評(píng)分,最終評(píng)分 6.5,不算低,共有短評(píng)六萬(wàn)多條,因?yàn)槎拱甑南拗?,游客身份只可以查看?200 條短評(píng),而登錄之后可以查看前 500 條短評(píng),同時(shí)我們還看到,影評(píng)有根據(jù)不同的維度分為熱門、最新和好友,為了獲取更多的數(shù)據(jù)樣本,我們將熱門和最新的評(píng)論都抓取下來。
其中我們要獲取的數(shù)據(jù)有評(píng)論人,評(píng)論時(shí)間,評(píng)論星級(jí)以及評(píng)論內(nèi)容,打開電影短評(píng)頁(yè)面然后將開發(fā)者工具調(diào)取出來。

我們發(fā)現(xiàn)所有的評(píng)論都是在一個(gè) class="comment" 的 div 中的,然后針對(duì)每一條評(píng)論,其對(duì)應(yīng)的位置都如上圖所示,唯一值得說明的是在我爬取數(shù)據(jù)的過程中,有的評(píng)論是獲取不到評(píng)論時(shí)間的,
因此我們可以定義一個(gè)獲取評(píng)論詳情的函數(shù),該函數(shù)接收一個(gè) URL 作為參數(shù),然后返回評(píng)論列表。
因?yàn)楂@取評(píng)論信息是需要登錄的,所以務(wù)必要將自己的 cookid 添加到 headers 中,否則是爬取不到評(píng)論的。
headers?=?{
????'User-Agent':?'Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_15_0)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/86.0.4240.111?Safari/537.36',
????'Referer':?'https://movie.douban.com',
????#?注意,這里需要加上你自己的?cookie
????'Cookie':?'.'
}
def?get_comment_by_url(url):
????#?評(píng)論人,評(píng)論時(shí)間,評(píng)論星級(jí)以及評(píng)論內(nèi)容
????users,,?times,?stars,?content_list?=?[],?[],?[],?[]
????data?=?requests.get(url,?headers=headers)
????selector?=?etree.HTML(data.text)
????comments?=?selector.xpath('//div[@class="comment"]')
????#?遍歷所有評(píng)論
????for?comment?in?comments:
????????user?=?comment.xpath('.//h3/span[2]/a/text()')[0]
????????star?=?comment.xpath('.//h3/span[2]/span[2]/@class')[0][7:8]
????????date_time?=?comment.xpath('.//h3/span[2]/span[3]/text()')
????????if?len(date_time)?!=?0:
????????????date_time?=?date_time[0].replace("\n",?"").strip()
????????else:
????????????date_time?=?None
????????comment_text?=?comment.xpath('.//p/span/text()')[0].strip()
????????users.append(user)
????????stars.append(star)
????????times.append(date_time)
????????content_list.append(comment_text)
????return?users,?stars,?times,?content_list
接下來我們來分析下評(píng)論頁(yè)面的 URL,如下所示:
https://movie.douban.com/subject/35155748/comments?start=40&limit=20&status=P&sort=new_score
每翻頁(yè)一次,start 都會(huì)增加 20,最大值為 480,其中最后的參數(shù) sort, 當(dāng) sort=new_score 表示按照熱門來排序,也即是最熱維度,當(dāng) sort=time 則表示根據(jù)時(shí)間來排序,也就是最新維度。
所以,我們可以使用以下函數(shù)來獲取所有評(píng)論。
def?get_comments():
????user_list,?star_list,?time_list,?comment_list?=?[],?[],?[],?[]
????for?sort?in?['time',?'new_score']:
????????sort_name?=?"最熱"?if?sort?==?'new_score'?else?'最新'
????????for?start?in?range(25):
????????????print('準(zhǔn)備抓取第?{}?頁(yè)數(shù)據(jù), 排序方式:{}'.format(start?+?1,?sort_name))
????????????users,?stars,?times,?comments?=?get_comment_by_url(base_url.format(start?*?20,?sort))
????????????if?not?users:
????????????????break
????????????user_list?+=?users
????????????star_list?+=?stars
????????????time_list?+=?times
????????????comment_list?+=?comments
????????????#?每次獲取數(shù)據(jù)之后暫停?5?秒
????????????time.sleep(5)
????result?=?{'users':?user_list,?'times':?time_list,?'stars':?star_list,?'comments':?comment_list}
????return?result
來看看我們獲取到的數(shù)據(jù),因?yàn)槲覀兪谦@取的熱門和最新兩個(gè)維度的數(shù)據(jù),而最新維度數(shù)據(jù)不足 500 條,所以總的數(shù)據(jù)量也就是 600 條左右。

數(shù)據(jù)分析
如上,我們獲取到了最終的數(shù)據(jù),接下來就可以做數(shù)據(jù)分析了。
評(píng)論量
首先來看看評(píng)論和日期的關(guān)系,也就是統(tǒng)計(jì)下每一天的評(píng)論量,以下代我是在 Jupyter Notebook 中運(yùn)行的。
bar?=?Bar()
bar.add_xaxis(index)
bar.add_yaxis("數(shù)量?&?時(shí)間",?values)
bar.set_global_opts(xaxis_opts=opts.AxisOpts(name="評(píng)論日期",?axislabel_opts={"rotate":?30}))
bar.render_notebook()
由上圖可以看出,10.23 和 10.24 評(píng)論數(shù)量爆表,原因是該劇是 10.23 上映的,之后評(píng)論數(shù)量逐級(jí)遞減,不過令人匪夷所思的是電影還未開始就已經(jīng)有人開始刷評(píng)論了,難道這就是傳說中的水軍么。

評(píng)論星級(jí)
在來統(tǒng)計(jì)下評(píng)分和日期的關(guān)系,為了方便統(tǒng)計(jì),我們?nèi)∶刻斓钠骄u(píng)論星級(jí)。
#?星級(jí)
df_time?=?df.groupby(['times']).size()
dic?=?{}
for?k?in?df_time.index:
????stars?=?df.loc[df['times']?==?str(k),?'stars']
????stars?=?list(map(int,?stars))
????dic[k]?=?round(sum(stars)?/?len(stars),?2)
bar_star?=?Bar()
bar_star.add_xaxis([x?for?x?in?dic.keys()])
bar_star.add_yaxis("星級(jí)?&?時(shí)間",?[x?for?x?in?dic.values()])
bar_star.set_global_opts(xaxis_opts=opts.AxisOpts(name="評(píng)論日期",?axislabel_opts={"rotate":?30}))
bar_star.render_notebook()

總體來看,該劇評(píng)論星級(jí)維持在 2.5~3.3 之間,結(jié)合 6.5 的評(píng)分來看,是比較吻合的。
演員
接下來我們分析下演員的受歡迎程度,實(shí)話講我是沖著吳京去看的這部劇,來看看最終結(jié)果如何。
roles?=?{'張譯':0,?'吳京':0,?'李九霄':0,?'魏晨':0,?'鄧超':0}
names?=?list(roles.keys())
for?row?in?df['comments']:
????for?name?in?names:
????????roles[name]?+=?row.count(name)
line?=?(
????Line()
????.add_xaxis(list(roles.keys()))
????.add_yaxis('',?list(roles.values()))
????.set_global_opts(title_opts=opts.TitleOpts(title=""))
)
line.render_notebook()

看來張譯的受歡迎程度最高,畢竟實(shí)力派演員,相反吳京的票數(shù)反而不是很高,有點(diǎn)奇怪,得票最少的是李九霄。
詞云
詞云圖可以更直觀的看到每個(gè)詞的出現(xiàn)頻率,最后我們?yōu)檫@部劇生成它專屬的詞云圖。
content?=?"".join(list(df['comments']))
#?jieba?分詞
words?=?jieba.cut(content)
word_list?=?[]
for?x?in?words:
????word_list.append(x)
cloud_word?=?','.join(word_list)
//?設(shè)置選項(xiàng)
wc?=?WordCloud(font_path='/System/Library/Fonts/PingFang.ttc',?background_color="white",?scale=2.5,
???????????????????contour_color="lightblue",?).generate(cloud_word)
plt.figure(figsize=(16,?9))
plt.imshow(wc)
plt.axis('off')
plt.show()

果然還是張譯出現(xiàn)的頻率較高。
總結(jié)
本文通過獲取「金剛川」的豆瓣影評(píng)對(duì)該劇做了一個(gè)定向分析,從結(jié)果可以看出大家評(píng)論星級(jí)和最終電影評(píng)分較吻合,演員張譯最受大家歡迎,剛上映時(shí)大家的評(píng)論熱情也最高,往后評(píng)論熱情越來越低。
雖說該劇最終得分 6.5 實(shí)屬不高,但這不應(yīng)該是一部以分?jǐn)?shù)高低來評(píng)價(jià)其好壞的電影,中國(guó)人民做了太多太多的犧牲和努力才換來了今天的和平盛世,甚至很多志愿軍都永遠(yuǎn)的留在了那里,片尾的那段解放軍接英雄們回家的片段真是讓人感傷至極,愿英雄們都可以落葉歸根,魂歸故里。
愿山河無恙,家國(guó)夢(mèng)圓!
PS:公號(hào)內(nèi)回復(fù)「Python」即可進(jìn)入Python 新手學(xué)習(xí)交流群,一起 100 天計(jì)劃!
老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點(diǎn)一下,如果感覺文章內(nèi)容不錯(cuò)的話,記得分享朋友圈讓更多的人知道!


【代碼獲取方式】
