我平時喜歡看電影,也會習慣性參考豆瓣電影評分,而豆瓣對於爬蟲愛好者是很友好的,沒有太多反爬措施,對新手是很友好的。html
本文將爬取豆瓣電影 TOP 250榜單的數據進行可視化,主要用了 BeautifulSoup
, pandas
, Matplotlib
等數據分析經常使用的庫。python
首先打開頁面,進入調試模式,咱們會看到以下頁面:微信
如圖所示,咱們能夠很直觀的看到數據,圖示信息就是咱們本次要爬取的信息。app
接下來,點擊頁面最下面的翻頁,咱們注意到第 2 頁的地址爲:movie.douban.com/top250?star… 第 3 頁的地址爲:movie.douban.com/top250?star…ide
不難發現其規律,那就開始寫代碼吧。學習
import os
import matplotlib.pyplot as plt
import pandas as pd
import requests
from bs4 import BeautifulSoup
def movies_spider():
records = []
for start in (range(250)[::25]):
url = f"https://movie.douban.com/top250?start={start}"
response = requests.get(url).text
soup = BeautifulSoup(response, 'html.parser')
movie_list = soup.find_all(class_='item')
for item in movie_list:
rank = int(item.find('em').string) # 排名
pic = item.find(class_='pic')
href = pic.find('a')['href'] # 連接
info = item.find(class_='info')
name = info.find(class_='title').string # 電影名稱
rating_num = info.find(class_='rating_num').string # 評分
total = info.find(
class_='rating_num').find_next_sibling().find_next_sibling().string[:-3] # 評價人數
inq = info.find(class_='inq') # 簡評
try:
quote = inq.get_text()
except AttributeError:
quote = None
print("Type error")
bd_div = item.find(class_='bd')
infos = bd_div.find('p').get_text().strip().split('\n')
# infos = ['導演: 弗蘭克·德拉邦特 Frank Darabont\xa0\xa0\xa0主演: 蒂姆·羅賓斯 Tim Robbins /...',
# ' 1994\xa0/\xa0美國\xa0/\xa0犯罪 劇情']
info1 = infos[0].split('\xa0\xa0\xa0')
director = info1[0][4:] # 導演
info2 = infos[1].lstrip().split('\xa0/\xa0')
year = info2[0][:4]
area = info2[1]
movie_type = info2[2]
movie = {
'rank': rank,
'name': name,
'director': director,
'year': year,
'area': area,
'type': movie_type,
'rating_num': rating_num,
'comment_num': total,
'quote': quote,
'url': href
}
records.append(movie)
return records
複製代碼
代碼配合前面的源代碼,仍是很好理解的,接下來先將數據保存爲 csv 文件,而後再利用 pandas 分析處理編碼
headers = ['rank', 'name', 'director', 'year', 'area', 'type', 'rating_num', 'comment_num',
'quote', 'url']
df = pd.DataFrame(rows, columns=headers)
df.to_csv('top250.csv')
複製代碼
咱們來看一下數據:url
先分析製片的國家地區,能夠看到,有的電影不止一個國家地區,好比霸王別姬的製片國家地區是:中國大陸 香港,所以咱們能夠用 split 進行處理spa
area_split = df['area'].str.split(' ').apply(pd.Series)
複製代碼
能夠看到電影最多有5個國家地區,咱們進行統計,求和,最後繪圖3d
a = area_split.apply(pd.value_counts)
area_count = a.sum(axis=1)
area_df = pd.DataFrame(area_count, columns=['count'], dtype=int).sort_values(by='count')
area_df.plot.barh()
複製代碼
美國以 144 部遙遙領先,香港 25 部排名第 4,中國大陸 17 部位居第 7
美國:144
日本:34
英國:34
香港:25
法國:21
咱們以一樣的方法分析分析電影類型
劇情片 191 部一樣遙遙領先,愛情、冒險、喜劇和犯罪,也是你們喜歡的類型。
劇情:192
愛情:57
冒險:47
喜劇:47
犯罪:44
前5的導演是:
克里斯托弗·諾蘭:7
宮崎駿:6
王家衛:5
史蒂文·斯皮爾伯格:5
李安:5
這幾位導演真是實至名歸
首先看一下排名前 10 的電影
排名 | 電影 | 評分 |
---|---|---|
1 | 肖申克的救贖 | 9.6 |
33 | 控方證人 | 9.6 |
2 | 霸王別姬 | 9.6 |
5 | 美麗人生 | 9.5 |
8 | 辛德勒的名單 | 9.5 |
3 | 這個殺手不太冷 | 9.4 |
4 | 阿甘正傳 | 9.4 |
32 | 十二怒漢 | 9.4 |
14 | 放牛班的春天 | 9.3 |
217 | 城市之光 | 9.3 |
注意到《城市之光》以 9.3 分排名 217,那麼咱們就會有疑問,評分與排名之間有什麼關係呢,咱們經過繪製散點圖和直方圖來分析
df.plot.scatter(x='rating_num', y='rank')
plt.title('評分與排名關係')
plt.xlabel('評分')
plt.ylabel('排名')
plt.gca().invert_yaxis()
df['rating_num'].plot.hist(bins=10, rwidth=0.9)
plt.title('評分分佈')
複製代碼
從上圖分析,隨着評分升高,排名也基本靠前,評分主要集中在 8.4~9.2
之間。同時能夠經過 pandas 計算平均數,衆數和相關係數,平均分爲 8.83
分,衆數爲 8.7
分,而相關係數爲 -0.6882
,評分與排名強相關。
評價人數前 10 電影
用以前一樣的方法,咱們來分析評價人數的分佈狀況以及評價人數和排名之間的關係
與評分不一樣的是,隨着評價人數的增多,電影排名有提早的趨勢,評價人數主要分佈在 10w-50w
之間,平均值爲 34.36w
,相關係數爲 -0.6865
,評價人數與排名強相關。
電影主要集中在 1990 年之後,相關係數爲 0.0173
,年份與排名沒有相關性。
最先的電影是在 1931 年,卓別林的《城市之光》
最近的電影是在 2017 年,三部
《請以你的名字呼喚我》:117
《三塊廣告牌》:191
《尋夢環遊記》:63
電影數量前三的年份分別是:
2010:14
2004:12
1994:11
沒想到貢獻了三部前 5 的電影大年 1994 也只能屈居第 3 位,最後咱們來看看貢獻數量最多的 2010 年都有哪些佳做
排名 | 電影 |
---|---|
9 | 盜夢空間 |
24 | 怦然心動 |
68 | 讓子彈飛 |
86 | 禁閉島 |
99 | 告白 |
118 | 馴龍高手 |
123 | 神偷奶爸 |
125 | 借東西的小人阿莉埃蒂 |
128 | 歲月神偷 |
142 | 黑天鵝 |
155 | 玩具總動員3 |
163 | 你看起來好像很好吃 |
214 | 初戀這件小事 |
237 | 國王的演講 |
本文僅對數據進行簡單的爬取分析和可視化,目的在於學習這些庫的基本使用,你還能夠進行深度挖掘分析,好比能夠進一步分析評價人數,評分,排名的關係,分析演員,語言以及時長等等,一個好的思路可能比技術更重要。
最後上一個 TOP250 全家福
願你在電影中碰見另外一個世界
願你在編碼中感覺學習的快樂
若是你對 Python 開發以及全棧工程師感興趣,歡迎關注微信公衆號,這裏不止 Python 哦