口碑撲街?Python告訴你《囧媽》到底囧在哪里?
“2020 年的春節(jié)檔之前被譽(yù)為神仙打架,各顯神通,可以說(shuō)是史上最強(qiáng)的春節(jié)檔,不料一場(chǎng)疫情,就換了另一個(gè)局面。為配合疫情的防控,春節(jié)檔電影全部撤檔。
本以為就這樣沒(méi)下文了,結(jié)果徐崢打出一張牌:線上免費(fèi)看《囧媽》,作為發(fā)行方的歡喜傳媒股票當(dāng)天也應(yīng)聲上漲 42%。今天我們就來(lái)聊聊另類春節(jié)檔的唯一一部電影《囧媽》。
《囧媽》繞過(guò)院線,全網(wǎng)免費(fèi)看
在《姜子牙》《唐人街探案 3》等片紛紛撤出春節(jié)檔之時(shí),《囧媽》突然宣布將于大年初一零點(diǎn)起,在抖音、西瓜視頻、今日頭條、歡喜首映等 App 上免費(fèi)上映,成為史上首部繞過(guò)院線直接網(wǎng)播的春節(jié)檔電影。
《囧媽》主要講的是小老板伊萬(wàn)纏身于商業(yè)糾紛,卻意外同母親坐上了開(kāi)往俄羅斯的火車。在旅途中,他和母親發(fā)生激烈沖突,同時(shí)還要和競(jìng)爭(zhēng)對(duì)手斗智斗勇。
為了最終抵達(dá)莫斯科,他不得不和母親共同克服難關(guān),并面對(duì)家庭生活中一直所逃避的問(wèn)題。
徐崢這次把《囧媽》免費(fèi)讓觀眾看的舉措,讓《囧媽》在慘淡的春節(jié)檔賺足了足夠的熱度,字節(jié)跳動(dòng)也收獲了大量的流量。該片三天總播出量超過(guò) 6 億人次,觀眾總數(shù)為 1.8 億人次。
敢做第一個(gè)吃螃蟹的人
回望中國(guó)電影「大票房」時(shí)代,國(guó)內(nèi)首部票房破 10 億的國(guó)產(chǎn)電影就是徐崢在 2012 年的作品《人再囧途之泰囧》,達(dá)到 12.67 億,之后國(guó)產(chǎn)電影就像打了雞血一樣,一個(gè)又一個(gè)破新高。
當(dāng)然這里面有 50% 的功勞要算在 2010 年前作《人在囧途》的精彩上,讓影迷們覺(jué)得囧系列和徐崢是品質(zhì)保證。
記得當(dāng)時(shí)看完《人在囧途》,就說(shuō)下次徐崢再拍囧系列一定要去電影院支持,這種口碑效應(yīng)在電影里面特別明顯。可能正是這樣的藝高,所以才膽大。
這次《囧媽》直接選擇線上首映,同時(shí)還把錢給掙了,弄的電影院聯(lián)名聲討,了解一下過(guò)程,你就懂了。
原來(lái)的形式是發(fā)行方歡喜傳媒拍好了電影,賣給橫店影視,保底 24 億票房。
然后橫店影視去找全國(guó)的電影院,你們幫我放這部電影,最后我們肯定至少能收入 24 億票房,咱們一起分。給發(fā)行方歡喜傳媒 6 個(gè)多億,然后我們?cè)俜质O碌?18 億,是個(gè)不錯(cuò)的生意。
而現(xiàn)在,是今日頭條直接取代了橫店影視的位置,我給你 6 個(gè)多億,我不用電影院放,我自己上億裝機(jī)量的 App 上就可以看,大家拿手機(jī)免費(fèi)看,我的 App 打開(kāi)率高了,錢就掙回來(lái)了,說(shuō)不定還能培養(yǎng)出大家用 App 看電影首映的習(xí)慣。
發(fā)行方歡喜傳媒,徐崢沒(méi)啥損失。電影院被今日頭條系給取代了,你說(shuō)能不聲討嗎?
觀眾看完之后是什么反應(yīng)
雖然《囧媽》賺足了流量,但口碑究竟如何呢?目前《囧媽》在豆瓣上的評(píng)分僅為 5.9 分,負(fù)面的評(píng)論居多。我們搜集整理了豆瓣上的評(píng)論數(shù)據(jù),用 Python 進(jìn)行分析。
整個(gè)數(shù)據(jù)分析的過(guò)程分為三步:
- 獲取數(shù)據(jù)
- 數(shù)據(jù)預(yù)處理
- 數(shù)據(jù)可視化
以下是具體的步驟和代碼實(shí)現(xiàn):
獲取數(shù)據(jù)
豆瓣從 2017 年 10 月開(kāi)始全面限制爬取數(shù)據(jù),非登錄狀態(tài)下最多獲取 200 條,登錄狀態(tài)下最多為 500 條,本次我們共獲取數(shù)據(jù) 698 條。
為了解決登錄的問(wèn)題,本次使用 Selenium+BeautifulSoup 獲取數(shù)據(jù)。
如下圖所示,本次數(shù)據(jù)爬取主要獲取的內(nèi)容有:
代碼實(shí)現(xiàn):
- # 導(dǎo)入所需包
- import requests
- from bs4 import BeautifulSoup
- import numpy as np
- import pandas as pd
- import time
- from selenium import webdriver
- from selenium.webdriver.common.by import By
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver.chrome.options import Options
- # 定義登錄函數(shù)
- def login_douban():
- '''功能:自動(dòng)登錄豆瓣網(wǎng)站'''
- global browser # 設(shè)置為全局變量
- browser = webdriver.Chrome()
- # 進(jìn)入登錄頁(yè)面
- login_url = 'https://accounts.douban.com/passport/login?source=movie'
- browser.get(login_url)
- # 點(diǎn)擊密碼登錄
- browser.find_element_by_class_name('account-tab-account').click()
- # 輸入賬號(hào)和密碼
- username = browser.find_element_by_id('username')
- username.send_keys('18511302788')
- password = browser.find_element_by_id('password')
- password.send_keys('12349148feng')
- # 點(diǎn)擊登錄
- browser.find_element_by_class_name('btn-account').click()
- # 定義函數(shù)獲取單頁(yè)數(shù)據(jù)
- def get_one_page(url):
- '''功能:傳入url,豆瓣電影一頁(yè)的短評(píng)信息'''
- # 進(jìn)入短評(píng)頁(yè)
- browser.get(url)
- # 使用bs解析網(wǎng)頁(yè)數(shù)據(jù)
- bs = BeautifulSoup(browser.page_source, 'lxml')
- # 獲取用戶名
- username = [i.find('a').text for i in bs.findAll('span', class_='comment-info')]
- # 獲取用戶url
- user_url = [i.find('a')['href'] for i in bs.findAll('span', class_='comment-info')]
- # 獲取推薦星級(jí)
- rating = []
- for i in bs.findAll('span', class_='comment-info'):
- try:
- one_rating = i.find('span', class_='rating')['title']
- rating.append(one_rating)
- except:
- rating.append('力薦')
- # 評(píng)論時(shí)間
- time = [i.find('span', class_='comment-time')['title'] for i in bs.findAll('span', class_='comment-info')]
- # 短評(píng)信息
- short = [i.text for i in bs.findAll('span', class_='short')]
- # 投票次數(shù)
- votes = [i.text for i in bs.findAll('span', class_='votes')]
- # 創(chuàng)建一個(gè)空的DataFrame
- df_one = pd.DataFrame()
- # 存儲(chǔ)信息
- df_one['用戶名'] = username
- df_one['用戶主頁(yè)'] = user_url
- df_one['推薦星級(jí)'] = rating
- df_one['評(píng)論時(shí)間'] = time
- df_one['短評(píng)信息'] = short
- df_one['投票次數(shù)'] = votes
- return df_one
- # 定義函數(shù)獲取25頁(yè)數(shù)據(jù)(目前所能獲取的最大頁(yè)數(shù))
- def get_25_page(movie_id):
- '''功能:傳入電影ID,獲取豆瓣電影25頁(yè)的短評(píng)信息'''
- # 創(chuàng)建空的DataFrame
- df_all = pd.DataFrame()
- # 循環(huán)追加
- for i in range(25):
- url = "https://movie.douban.com/subject/{}/comments?start={}&limit=20&sort=new_score&status=P".format(movie_id,i*20)
- print('我正在抓取第{}頁(yè)'.format(i+1), end='\r')
- # 調(diào)用函數(shù)
- df_one = get_one_page(url)
- df_all = df_all.append(df_one, ignore_index=True)
- # 程序休眠一秒
- time.sleep(1.5)
- return df_all
- if __name__ == '__main__':
- # 先運(yùn)行登錄函數(shù)
- login_douban()
- # 程序休眠兩秒
- time.sleep(2)
- # 再運(yùn)行循環(huán)翻頁(yè)函數(shù)
- movie_id = 30306570 # 囧媽
- df_all = get_25_page(movie_id)
爬取出來(lái)的數(shù)據(jù)以數(shù)據(jù)框的形式存儲(chǔ),結(jié)果如下所示:
從用戶主頁(yè)的地址可以獲取到用戶的城市信息,這一步比較簡(jiǎn)單,此處的代碼省略。
數(shù)據(jù)預(yù)處理
對(duì)于獲取到的數(shù)據(jù),我們需要進(jìn)行以下的處理以方便后續(xù)分析:
- 推薦星級(jí):轉(zhuǎn)換為 1-5 分。
- 評(píng)論時(shí)間:轉(zhuǎn)換為時(shí)間類型,提取出日期信息。
- 城市:有城市空缺、海外城市、亂寫和 pyecharts 尚不支持的城市,需要進(jìn)行處理。
- 短評(píng)信息:需要進(jìn)行分詞和提取關(guān)鍵詞。
代碼實(shí)現(xiàn):
- # 定義函數(shù)轉(zhuǎn)換推薦星級(jí)字段
- def transform_star(x):
- if x == '力薦':
- return 5
- elif x == '推薦':
- return 4
- elif x == '還行':
- return 3
- elif x == '較差':
- return 2
- else:
- return 1
- # 星級(jí)轉(zhuǎn)換
- df_all['星級(jí)'] = df_all.推薦星級(jí).map(lambda x:transform_star(x))
- # 轉(zhuǎn)換日期類型
- df_all['評(píng)論時(shí)間'] = pd.to_datetime(df_all.評(píng)論時(shí)間)
- # 提取日期
- df_all['日期'] = df_all.評(píng)論時(shí)間.dt.date
- # 定義函數(shù)-獲取短評(píng)信息關(guān)鍵詞
- def get_comment_word(df):
- '''功能:傳入df,提取短評(píng)信息關(guān)鍵詞'''
- # 導(dǎo)入庫(kù)
- import jieba.analyse
- import os
- # 去停用詞
- stop_words = set()
- # 加載停用詞
- cwd = os.getcwd()
- stop_words_path = cwd + '\\stop_words.txt'
- with open(stop_words_path, 'r', encoding='utf-8') as sw:
- for line in sw.readlines():
- stop_words.add(line.strip())
- # 添加停用詞
- stop_words.add('6.3')
- stop_words.add('一張')
- stop_words.add('一部')
- stop_words.add('徐崢')
- stop_words.add('徐導(dǎo)')
- stop_words.add('電影')
- stop_words.add('電影票')
- # 合并評(píng)論信息
- df_comment_all = df['短評(píng)信息'].str.cat()
- # 使用TF-IDF算法提取關(guān)鍵詞
- word_num = jieba.analyse.extract_tags(df_comment_all, topK=100, withWeight=True, allowPOS=())
- # 做一步篩選
- word_num_selected = []
- # 篩選掉停用詞
- for i in word_num:
- if i[0] not in stop_words:
- word_num_selected.append(i)
- else:
- pass
- return word_num_selected
- key_words = get_comment_word(df_all)
- key_words = pd.DataFrame(key_words, columns=['words','num'])
數(shù)據(jù)可視化
用 Python 做可視化分析的工具很多,目前比較好用可以實(shí)現(xiàn)動(dòng)態(tài)可視化的是 pyecharts。
我們主要對(duì)以下幾個(gè)方面信息進(jìn)行可視化分析:
- 總體評(píng)分分布
- 評(píng)分時(shí)間走勢(shì)圖
- 評(píng)論用戶城市分布
- 評(píng)論詞云圖
①總體評(píng)分分布
《囧媽》截止到目前在豆瓣中的總體評(píng)分為 5.9 分,僅好于 19% 的喜劇片。從評(píng)分分布來(lái)看,3 分的占比最高,有 36.39%,其次為 2 分,有 32.09%,5 分的比例最低,僅有 6.88%。
代碼實(shí)現(xiàn):
- # 總體評(píng)分百分比
- score_perc = df_all.星級(jí).value_counts() / df_all.星級(jí).value_counts().sum()
- score_perc = np.round(score_perc*100,2)
- # 導(dǎo)入所需包
- from pyecharts import options as opts
- from pyecharts.charts import Pie, Page
- # 繪制柱形圖
- pie1 = Pie(init_opts=opts.InitOpts(width='1350px', height='750px'))
- pie1.add("",
- [*zip(score_perc.index, score_perc.values)],
- radius=["40%","75%"])
- pie1.set_global_opts(title_opts=opts.TitleOpts(title='總體評(píng)分分布'),
- legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
- toolbox_opts=opts.ToolboxOpts())
- pie1.set_series_opts(label_opts=opts.LabelOpts(formatter="{c}%"))
- pie1.render('總體評(píng)分分布.html')
②評(píng)分時(shí)間走勢(shì)圖
評(píng)論的時(shí)間走勢(shì)圖和電影熱度一致,在大年初一免費(fèi)上映時(shí)候達(dá)到最高值。
代碼實(shí)現(xiàn):
- # 時(shí)間排序
- time = df_all.日期.value_counts()
- time.sort_index(inplace=True)
- from pyecharts.charts import Line
- # 繪制時(shí)間走勢(shì)圖
- line1 = Line(init_opts=opts.InitOpts(width='1350px', height='750px'))
- line1.add_xaxis(time.index.tolist())
- line1.add_yaxis('評(píng)論熱度', time.values.tolist(), areastyle_opts=opts.AreaStyleOpts(opacity=0.5), label_opts=opts.LabelOpts(is_show=False))
- line1.set_global_opts(title_opts=opts.TitleOpts(title="時(shí)間走勢(shì)圖"), toolbox_opts=opts.ToolboxOpts())
- line1.render('評(píng)論時(shí)間走勢(shì)圖.html')
③評(píng)論用戶城市分布
接下來(lái)分析了評(píng)論者所在的城市分布。
首先是用條形圖,來(lái)粗略的展示前十大熱門的影迷城市。
代碼實(shí)現(xiàn):
- # 國(guó)內(nèi)城市top10
- city_top10 = df_all.城市處理.value_counts()[:12]
- city_top10.drop('國(guó)外', inplace=True)
- city_top10.drop('未知', inplace=True)
- from pyecharts.charts import Bar
- # 條形圖
- bar1 = Bar(init_opts=opts.InitOpts(width='1350px', height='750px'))
- bar1.add_xaxis(city_top10.index.tolist())
- bar1.add_yaxis("城市", city_top10.values.tolist())
- bar1.set_global_opts(title_opts=opts.TitleOpts(title="評(píng)論者Top10城市分布"),toolbox_opts=opts.ToolboxOpts())
- bar1.render('評(píng)論者Top10城市分布條形圖.html')
柱形圖的展示不是很直觀也不全面,在含有地理位置的數(shù)據(jù)中,我們常采用地圖的形式。
為大家更加直觀的進(jìn)行展示,選取了觀影城市最多的前三十個(gè)城市作為動(dòng)態(tài)展示,如下圖所示:
代碼實(shí)現(xiàn):
- city_num = df_all.城市處理.value_counts()[:30]
- city_num.drop('國(guó)外', inplace=True)
- city_num.drop('未知', inplace=True)
- c1 = Geo(init_opts=opts.InitOpts(width='1350px', height='750px'))
- c1.add_schema(maptype='china')
- c1.add('geo', [list(z) for z in zip(city_num.index, city_num.values.astype('str'))], type_=ChartType.EFFECT_SCATTER)
- c1.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
- c1.set_global_opts(visualmap_opts=opts.VisualMapOpts(),
- title_opts=opts.TitleOpts(title='評(píng)論者城市分布'),
- toolbox_opts=opts.ToolboxOpts())
- c1.render('評(píng)論者城市分布地圖.html')
④評(píng)論詞云圖
從詞云圖中可以看出,"喜劇" "和解" "母子" "笑點(diǎn)" "親情"等詞占較大的比重。
骨子里還是囧系列那種公路喜劇片,這次用母子關(guān)系制造一系列的笑點(diǎn),讓電影的主題表達(dá)更進(jìn)一步。
但也有很多觀眾反映電影強(qiáng)行煽情,強(qiáng)行上升高度,強(qiáng)行搞笑,強(qiáng)行接續(xù)劇情,強(qiáng)行中年婚姻危機(jī)。
代碼實(shí)現(xiàn):
- from pyecharts.charts import WordCloud
- from pyecharts.globals import SymbolType, ThemeType
- word = WordCloud(init_opts=opts.InitOpts(width='1350px', height='750px'))
- word.add("", [*zip(key_words.words, key_words.num)], word_size_range=[20, 200])
- word.set_global_opts(title_opts=opts.TitleOpts(title="囧媽電影評(píng)論詞云圖"),
- toolbox_opts=opts.ToolboxOpts())
- word.render('囧媽電影評(píng)論詞云圖.html')
在熱門評(píng)論里,用戶阿暖說(shuō)道:“ 很平庸,很無(wú)趣,既不好笑,對(duì)于原生家庭的探討也只是隔靴搔癢而已。”
竟然獲得了 5560 個(gè)贊同。
同時(shí)我也查了一下:
- 2010 年《人在囧途》,豆瓣 7.7 分。主演是徐崢,導(dǎo)演葉偉民。
- 2012 年《人在囧途之泰囧》,豆瓣 7.4 分,徐崢自導(dǎo)自演。
- 2015 年《港囧》,豆瓣 5.7 分,徐崢自導(dǎo)自演。
- 2018 年《我不是藥神》,豆瓣 9.0 分,主演是徐崢,導(dǎo)演是文牧野。
- 2020 年《囧媽》,豆瓣 5.9 分,徐崢自導(dǎo)自演。
所以徐崢一定是個(gè)好演員,但導(dǎo)演嘛,就不好說(shuō)了。
有人說(shuō)這次徐崢這個(gè)玩法是要做中國(guó)版的 Netflix。Netflix 現(xiàn)在大家都知道是世界數(shù)一數(shù)二流媒體平臺(tái),就是視頻網(wǎng)站,也能在電視上看。
所以從口碑上看,《囧媽》只能算在形式上開(kāi)了個(gè)頭,就像當(dāng)年徐崢是開(kāi)啟了中國(guó)電影的大票房時(shí)代,但真正的票房王是吳京,讓我們期待一下吧。





























