去年底的時候,我招收了新的「實訓生」。本文是其中一位 @齊大聖 同窗在實訓兩個月時完成的項目案例。(碼上行動羣裏同窗應該都看過這個名字,如今也是助教之一。)項目最初的想法是,從互聯網上的公開信息中採集2018年在國內上映電影的票房、評分、類型、演員等信息,而後作一些數據分析和可視化展現。這樣一個項目,除了須要對 python 基本語法和數據結構的掌握以外,還涉及到網頁分析、爬蟲、文本解析、數據庫存儲、數據處理、數據分析、數據可視化,而且須要對一個完整項目有總體的模塊設計,對於編程學習者來講是從入門到進階的一個很好案例。常常跟我說學了基礎不知道作什麼項目的同窗們,別光顧着看熱鬧,回頭本身也動手作一作。代碼已上傳,獲取見文末。html
項目之初,咱們的想法主要是對去年國內上映電影的票房、評分進行一下排行,而後按不一樣類型對比下,什麼片更受歡迎,什麼片更賺錢。後來開發過程當中,正值《流浪地球》大賣,吳京成爲首位國內票房破百億的演員。因而咱們突發奇想,來看一看誰是去年單年累積票房最高的演員。是《我不是藥神》的徐崢,仍是《唐人街探案2》的王寶強(他倆還合演了《一出好戲》),又或者是《紅海行動》中的某位?python
在往下看以前,你也能夠大膽猜一下。但我打賭你是猜不到的。若是沒猜對,記得幫忙轉發點贊。mongodb
這個排名你們都不陌生,沒啥好多說的,好玩的在後面。數據庫
咱們將全部電影按評分和票房作成散點分佈圖,獲得上述圖片。此圖是動態可交互的,這裏我截幾張有表明性的(點擊圖片後可放大):編程
依次是動做、喜劇、劇情、動畫四類電影分佈。粗略一看,動做片是比較受市場歡迎的,畢竟選擇去觀看大屏幕,很大程度也是爲了享受特效和視聽感覺。喜劇和劇情也還不錯,但高票房的動畫片就不多了。json
這張圖是不一樣影片類型的數量和評分狀況。劇情、喜劇、動做是三大主流類型。api
從評分上看,動畫片最高,我很早就發現了這個現象,我以爲多是由於動畫片類型明確,會觀看並評價的人自己對其接受度高,而不喜歡的人壓根兒就不會去看。劇情片總體評分也不錯,可見能把一個故事說好,觀衆就挺滿意了。愛情片、驚悚片則是一貫是爛片的高發地帶。數據結構
說明下:這裏的類型是重複計算的,一部片會既是動做片,又是喜劇片。另外因爲豆瓣上一些電影評分數量太少而不顯示,因此這裏的電影數量會和票房數量有所差別。echarts
從票房上看,動做片不論是總量仍是平均,都很強勢。值得注意的是科幻片,雖然通常認爲這是個小衆類型,但與廣義科幻沾邊的影片平均票房卻不低(這裏面Marvel貢獻了很多),今年的小破球更是創造了新的紀錄。戰爭片則是被《紅海行動》一片之力拉高了平均值。工具
將類型片的票房按月劃分,獲得了這張圖。春節檔無疑是一年最搶錢的檔期,而喜劇片又是此檔期的絕對主力。暑期檔則是另外一個票房小高峯。動做片一年四季都不錯。
這裏的月度劃分是按首映日期,因此會有一些提早,好比國慶檔的票房都記在了九月份。
以上面幾組數據來看,若是哪位土豪讀者想投資拍電影,選擇動做片是比較保險的,記得要把故事說好,最好再加點科幻元素,在春節前上映。
這裏作了 IMDB、時光網、貓眼分別和豆瓣評分的關係對比。
按理說,若是兩個網站的評分基本一致的話,這些點應當分佈在對角線上。IMDB、時光網和豆瓣仍是差很少的(豆瓣實際上是5星制,最低2分)。再細分一下,時光網和豆瓣的相關性要比 IMDB 更大(文化差別),好片比爛片的相關性更大(好片都說好,爛片則口味不一樣)。
有意思的是貓眼(最右側圖),它的評分廣泛要比豆瓣高,相信不少人都有直觀感覺。固然這也有它的緣由:貓眼買了票的人才會評分,那通常總歸會選個本身愛看的吧。
【彩蛋】圖上右下角有個使人矚目的孤點,這部電影是個例外,它貓眼評分2.9,豆瓣卻有6.9,你知道是哪部嗎?(能夠留言猜一下,我待會兒在留言中公佈答案)若是你瞭解此片背後的故事,定會一拍大腿恍然大悟。
好了,到了公佈最終結果的時候。
第一名:王成思
參演電影:《西紅柿首富》25億;《唐人街探案2》34億;《李茶的姑媽》6億
這……是誰啊,演的誰……
斯坦·李憑藉各類客串,位列第3。而另外一位能在Marvel、DC兩道均能跑龍套的約翰·蓋蒂爾,也躋身前十,一樣也不知道他演的角色……
怎麼樣,有沒有出乎你的意料?如今你能夠拿這個去問別人了
全部圖表在網頁上都是動態可交互的,訪問地址請在咱們公衆號(Crossin的編程教室)裏回覆關鍵字 票房
代碼也已上傳,並附帶有說明文檔,大體說明了實現思路、文件說明、技術細節。一樣回覆關鍵字 票房
若是你想要跟着實現或運行相關代碼,我這裏再簡單說幾點。
項目總體思路:
開發環境及所需庫:
有幾點值得注意的是:
部分代碼(僅演示,完整代碼見項目倉庫):
抓取並保存
client = pymongo.MongoClient()
db = client.chinamovies # 獲取或新建名爲 chinamovies 的 database
collections = db.movies # 獲取或者新建了一個表
url_origin = 'http://www.cbooo.cn/Mdata/getMdata_movie?area={area}&type=0&year=2018&initial=%E5%85%A8%E9%83%A8&pIndex={page}'
url = url_origin.format(area=area, page=page)
req = requests.get(url, headers=headers)
data = req.json()
collections.insert_many(data['pData'])複製代碼
獲取豆瓣信息
url_api = 'https://api.douban.com/v2/movie/search?q={}'.format(moviename)
req = requests.get(url_api, headers=headers)
data_total = req.json()['subjects']
if not data_total:
print('你搜索的不存在:', moviename)
else:
print(data_total[0])複製代碼
計算影人蔘演票房總和
for i in col_casts.find():
total_box = 0
for j in i['movie_id']:
movie = collections_detail.find_one({'id': j})
if movie['boxoffice']:
total_box += int(movie['boxoffice'])
col_casts.update_one({'_id': i['_id']}, {'$set': {'total_box': total_box}}, upsert=True)複製代碼
輸出票房/評分分佈散點圖
scatter = Scatter("電影評分-票房")
total_num = 0
for i in genre:
total_num += len(genre[i]['rate'])
scatter.add(i, genre[i]['boxoffice'], genre[i]['rate'], **other_setting, extra_name=genre[i]['title'],
xaxis_name='票房(億)', yaxis_name='評分', yaxis_name_gap=20,yaxis_min=2, symbol_size=5,
label_formatter='{c}', is_label_emphasis=True, is_toolbox_show=False)
scatter.render('電影評分-票房.html')複製代碼
查看交互圖表和代碼地址,請在公衆號(Crossin的編程教室)回覆關鍵字 票房
════
其餘文章及回答:
學編程:如何自學Python | 新手引導 | 一圖學Python
歡迎搜索及關注:Crossin的編程教室