史上最詳細(xì)Python爬取電影教程,還不會那也是沒誰了

摘要:?作為小白,爬蟲可以說是入門python最快和最容易獲得成就感的途徑。因為初級爬蟲的套路相對固定,常見的方法只有幾種,比較好上手。選取網(wǎng)頁結(jié)構(gòu)較為簡單的貓眼top100電影為案例進(jìn)行練習(xí)。?重點是用上述所說的4種方法提取出關(guān)鍵內(nèi)容。一個問題采用不同的解決方法有助于拓展思維,通過不斷練習(xí)就能夠靈活運(yùn)用。

小編推薦大家可以加我的扣扣群 735934841 ,免費(fèi)領(lǐng)取10本Python 學(xué)習(xí)資料

本文知識點:?Requsts 請求庫的使用 beautiful+lxml兩大解析庫使用 正則表達(dá)式 、xpath、css選擇器的使用

1. 為什么爬取該網(wǎng)頁?

比較懶,不想一頁頁地去翻100部電影的介紹,想在一個頁面內(nèi)進(jìn)行總體瀏覽(比如在excel表格中);

深入了解一些比較有意思的信息,比如:哪部電影的評分最高?哪位演員的作品數(shù)量最多?哪個國家/地區(qū)上榜的電影數(shù)量最多?哪一年上榜的電影作品最多等。這些信息在網(wǎng)頁上是不那么容易能直接獲得的,所以需要爬蟲。

2. 爬蟲目標(biāo)

從網(wǎng)頁中提取出top100電影的電影名稱、封面圖片、排名、評分、演員、上映國家/地區(qū)、評分等信息,并保存為csv文本文件。

根據(jù)爬取結(jié)果,進(jìn)行簡單的可視化分析。

平臺:windows7 + SublimeText3

3. 爬取步驟

3.1. 網(wǎng)址URL分析

首先,打開貓眼Top100的url網(wǎng)址:?http://maoyan.com/board/4?offset=0。頁面非常簡單,所包含的信息就是上述所說的爬蟲目標(biāo)。下拉頁面到底部,點擊第2頁可以看到網(wǎng)址變?yōu)椋?b>http://maoyan.com/board/4?offset=10。因此,可以推斷出url的變化規(guī)律:offset表示偏移,10代表一個頁面的電影偏移數(shù)量,即:第一頁電影是從0-10,第二頁電影是從11-20。因此,獲取全部100部電影,只需要構(gòu)造出10個url,然后依次獲取網(wǎng)頁內(nèi)容,再用不同的方法提取出所需內(nèi)容就可以了。

下面,用requests方法獲取第一個頁面。

3.2. Requests獲取首頁數(shù)據(jù)

先定義一個獲取單個頁面的函數(shù):get_one_page(),傳入url參數(shù)。

1def get_one_page(url):

2 try:

3 headers = {

4 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}

5 # 不加headers爬不了

6 response = requests.get(url, headers=headers)

7 if response.status_code == 200:

8 return response.text

9 else:

10 return None

11 except RequestException:

12 return None

13 # try-except語句捕獲異常

接下來在main()函數(shù)中設(shè)置url。

1def main():

2 url = 'http://maoyan.com/board/4?offset=0'

3 html = get_one_page(url)

4 print(html)

5

6

7if __name__ == '__main__':

8 main()

運(yùn)行上述程序后,首頁的源代碼就被爬取下來了。如下圖所示:

接下來就需要從整個網(wǎng)頁中提取出幾項我們需要的內(nèi)容,用到的方法就是上述所說的四種方法,下面分別進(jìn)行說明。

3.3. 4種內(nèi)容解析提取方法

3.3.1. 正則表達(dá)式提取

第一種是利用正則表達(dá)式提取。

什么是正則表達(dá)式? 下面這串看起來亂七八糟的符號就是正則表達(dá)式的語法。

1'.*?board-index.*?>(d+).*?src="(.*?)".*?name">(.*?).*?'

它是一種強(qiáng)大的字符串處理工具。之所以叫正則表達(dá)式,是因為它們可以識別正則字符串(regular string)。可以這么定義:“ 如果你給我的字符串符合規(guī)則,我就返回它”;“如果字符串不符合規(guī)則,我就忽略它”。通過requests抓取下來的網(wǎng)頁是一堆大量的字符串,用它處理后便可提取出我們想要的內(nèi)容。

如果還不了解它,可以參考下面的教程:

http://www.runoob.com/regexp/regexp-syntax.htmlhttps://www.w3cschool.cn/regexp/zoxa1pq7.html

下面,開始提取關(guān)鍵內(nèi)容。右鍵網(wǎng)頁-檢查-Network選項,選中左邊第一個文件然后定位到電影信息的相應(yīng)位置,如下圖:

可以看到每部電影的相關(guān)信息都在dd這個節(jié)點之中。所以就可以從該節(jié)點運(yùn)用正則進(jìn)行提取。

第1個要提取的內(nèi)容是電影的排名。它位于class="board-index"的i節(jié)點內(nèi)。不需要提取的內(nèi)容用'.*?'替代,需要提取的數(shù)字排名用()括起來,()里面的數(shù)字表示為(d+)。正則表達(dá)式可以寫為:

1'.*?board-index.*?>(d+)'

接著,第2個需要提取的是封面圖片,圖片網(wǎng)址位于img節(jié)點的'src'屬性中,正則表達(dá)式可寫為:

1'src="(.*?)".*?'

第1和第2個正則之間的代碼是不需要的,用'.*?'替代,所以這兩部分合起來寫就是:

1'.*?board-index.*?>(d+).*?src="(.*?)"

同理,可以依次用正則寫下主演、上映時間和評分等內(nèi)容,完整的正則表達(dá)式如下:

1'.*?board-index.*?>(d+).*?src="(.*?)".*?name">(.*?).*?star">(.*?).*?releasetime">(.*?)(.*?).*?fraction">(.*?).*?'

正則表達(dá)式寫好以后,可以定義一個頁面解析提取方法:parse_one_page(),用來提取內(nèi)容:

1def parse_one_page(html):

2 pattern = re.compile(

3 '.*?board-index.*?>(d+).*?src="(.*?)".*?name">(.*?).*?star">(.*?).*?releasetime">(.*?)(.*?).*?fraction">(.*?).*?', re.S)

4 # re.S表示匹配任意字符,如果不加,則無法匹配換行符

5 items = re.findall(pattern, html)

6 # print(items)

7 for item in items:

8 yield {

9 'index': item[0],

10 'thumb': get_thumb(item[1]), # 定義get_thumb()方法進(jìn)一步處理網(wǎng)址

11 'name': item[2],

12 'star': item[3].strip()[3:],

13 # 'time': item[4].strip()[5:],

14 # 用兩個方法分別提取time里的日期和地區(qū)

15 'time': get_release_time(item[4].strip()[5:]),

16 'area': get_release_area(item[4].strip()[5:]),

17 'score': item[5].strip() + item[6].strip()

18 # 評分score由整數(shù)+小數(shù)兩部分組成

19 }

Tips:?re.S:匹配任意字符,如果不加,則無法匹配換行符;?yield:使用yield的好處是作為生成器,可以遍歷迭代,并且將數(shù)據(jù)整理形成字典,輸出結(jié)果美觀。具體用法可參考:https://blog.csdn.net/zhangpinghao/article/details/18716275;?.strip():用于去掉字符串中的空格。

上面程序為了便于提取內(nèi)容,又定義了3個方法:get_thumb()、get_release_time()和 get_release_area():

1# 獲取封面大圖

2def get_thumb(url):

3 pattern = re.compile(r'(.*?)@.*?')

4 thumb = re.search(pattern, url)

5 return thumb.group(1)

6# http://p0.meituan.net/movie/5420be40e3b755ffe04779b9b199e935256906.jpg@160w_220h_1e_1c

7# 去掉@160w_220h_1e_1c就是大圖

8

9

10# 提取上映時間函數(shù)

11def get_release_time(data):

12 pattern = re.compile(r'(.*?)((|$)')

13 items = re.search(pattern, data)

14 if items is None:

15 return '未知'

16 return items.group(1) # 返回匹配到的第一個括號(.*?)中結(jié)果即時間

17

18

19# 提取國家/地區(qū)函數(shù)

20def get_release_area(data):

21 pattern = re.compile(r'.*((.*))')

22 # $表示匹配一行字符串的結(jié)尾,這里就是(.*?);(|$,表示匹配字符串含有(,或者只有(.*?)

23 items = re.search(pattern, data)

24 if items is None:

25 return '未知'

26 return items.group(1)

Tips:?'r':正則前面加上'r' 是為了告訴編譯器這個string是個raw string,不要轉(zhuǎn)意''。當(dāng)一個字符串使用了正則表達(dá)式后,最好在前面加上'r';?'|'?正則'|'表示或','′:??正則′∣′表示或′,′'表示匹配一行字符串的結(jié)尾;?.group(1):意思是返回search匹配的第一個括號中的結(jié)果,即(.*?),gropup()則返回所有結(jié)果2013-12-18(,group(1)返回'('。

接下來,修改main()函數(shù)來輸出爬取的內(nèi)容:

1def main():

2 url = 'http://maoyan.com/board/4?offset=0'

3 html = get_one_page(url)

4

5 for item in parse_one_page(html):

6 print(item)

7

8

9if __name__ == '__main__':

10 main()

Tips:?if?_ name_?== '_?main_':當(dāng).py文件被直接運(yùn)行時,if?_ name_?== '_?main_'之下的代碼塊將被運(yùn)行;當(dāng).py文件以模塊形式被導(dǎo)入時,if?_ name_?== '_?main_'之下的代碼塊不被運(yùn)行。 參考:https://blog.csdn.net/yjk13703623757/article/details/77918633。

運(yùn)行程序,就可成功地提取出所需內(nèi)容,結(jié)果如下:

1{'index': '1', 'thumb': 'http://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg', 'name': '霸王別姬', 'star': '張國榮,張豐毅,鞏俐', 'time': '1993-01-01', 'area': '中國香港', 'score': '9.6'}

2{'index': '2', 'thumb': 'http://p0.meituan.net/movie/54617769d96807e4d81804284ffe2a27239007.jpg', 'name': '羅馬假日', 'star': '格利高里·派克,奧黛麗·赫本,埃迪·艾伯特', 'time': '1953-09-02', 'area': '美國', 'score': '9.1'}

3{'index': '3', 'thumb': 'http://p0.meituan.net/movie/283292171619cdfd5b240c8fd093f1eb255670.jpg', 'name': '肖申克的救贖', 'star': '蒂姆·羅賓斯,摩根·弗里曼,鮑勃·岡頓', 'time': '1994-10-14', 'area': '美國', 'score': '9.5'}

4{'index': '4', 'thumb': 'http://p0.meituan.net/movie/e55ec5d18ccc83ba7db68caae54f165f95924.jpg', 'name': '這個殺手不太冷', 'star': '讓·雷諾,加里·奧德曼,娜塔莉·波特曼', 'time': '1994-09-14', 'area': '法國', 'score': '9.5'}

5{'index': '5', 'thumb': 'http://p1.meituan.net/movie/f5a924f362f050881f2b8f82e852747c118515.jpg', 'name': '教父', 'star': '馬龍·白蘭度,阿爾·帕西諾,詹姆斯·肯恩', 'time': '1972-03-24', 'area': '美國', 'score': '9.3'}

6

7...

8}

9[Finished in 1.9s]

以上是第1種提取方法,如果還不習(xí)慣正則表達(dá)式這種復(fù)雜的語法,可以試試下面的第2種方法。

3.3.2. lxml結(jié)合xpath提取

該方法需要用到lxml這款解析利器,同時搭配xpath語法,利用它的的路徑選擇表達(dá)式,來高效提取所需內(nèi)容。lxml包為第三方包,需要自行安裝。如果對xpath的語法還不太熟悉,可參考下面的教程:

http://www.w3school.com.cn/xpath/xpath_syntax.asp

1

2

3

4

5

6

7

8

9

2018-08-18已更新

10

榜單規(guī)則:將貓眼電影庫中的經(jīng)典影片,按照評分和評分人數(shù)從高到低綜合排序取前100名,每天上午10點更新。相關(guān)數(shù)據(jù)來源于“貓眼電影庫”。

11

12

13 1

14

17

18

19

20

21

霸王別姬

22

23 主演:張國榮,張豐毅,鞏俐

24

25

上映時間:1993-01-01(中國香港)

26

27

9.6

28

29

30

31

32

33

34

根據(jù)截取的部分html網(wǎng)頁,先來提取第1個電影排名信息,有兩種方法。

第一種:直接復(fù)制。

右鍵-Copy-Copy Xpath,得到xpath路徑為://*[@id="app"]/div/div/div[1]/dl/dd[1]/i,為了能夠提取到頁面所有的排名信息,需進(jìn)一步修改為://*[@id="app"]/div/div/div[1]/dl/dd/i/text(),如果想要再精簡一點,可以省去中間部分絕對路徑'/'然后用相對路徑'//'代替,最后進(jìn)一步修改為://*[@id="app"]//div//dd/i/text()。

第二種:觀察網(wǎng)頁結(jié)構(gòu)自己寫。

首先注意到id = app的div節(jié)點,因為在整個網(wǎng)頁結(jié)構(gòu)id是唯一的不會有第二個相同的,所有可以將該div節(jié)點作為xpath語法的起點,然后往下觀察分別是3級div節(jié)點,可以省略寫為://div,再往下分別是是兩個并列的p節(jié)點、dl節(jié)點、dd節(jié)點和最后的i節(jié)點文本。中間可以隨意省略,只要保證該路徑能夠選擇到唯一的文本值'1'即可,例如省去p和dl節(jié)點,只保留后面的節(jié)點。這樣,完整路徑可以為://*[@id="app"]//div//dd/i/text(),和上式一樣。

根據(jù)上述思路,可以寫下其他內(nèi)容的xpath路徑。觀察到路徑的前一部分://*[@id="app"]//div//dd都是一樣的,從后面才開始不同,因此為了能夠精簡代碼,將前部分路徑賦值為一個變量items,最終提取的代碼如下:

1# 2 用lxml結(jié)合xpath提取內(nèi)容

2def parse_one_page2(html):

3 parse = etree.HTML(html)

4 items = parse.xpath('//*[@id="app"]//div//dd')

5 # 完整的是//*[@id="app"]/div/div/div[1]/dl/dd

6 # print(type(items))

7 # *代表匹配所有節(jié)點,@表示屬性

8 # 第一個電影是dd[1],要提取頁面所有電影則去掉[1]

9 # xpath://*[@id="app"]/div/div/div[1]/dl/dd[1]

10 for item in items:

11 yield{

12 'index': item.xpath('./i/text()')[0],

13 #./i/text()前面的點表示從items節(jié)點開始

14 #/text()提取文本

15 'thumb': get_thumb(str(item.xpath('./a/img[2]/@src')[0].strip())),

16 # 'thumb': 要在network中定位,在elements里會寫成@src而不是@src,從而會報list index out of range錯誤。

17 'name': item.xpath('./a/@title')[0],

18 'star': item.xpath('.//p[@class = "star"]/text()')[0].strip(),

19 'time': get_release_time(item.xpath(

20 './/p[@class = "releasetime"]/text()')[0].strip()[5:]),

21 'area': get_release_area(item.xpath(

22 './/p[@class = "releasetime"]/text()')[0].strip()[5:]),

23 'score' : item.xpath('.//p[@class = "score"]/i[1]/text()')[0] +

24 item.xpath('.//p[@class = "score"]/i[2]/text()')[0]

25 }

Tips:?[0]:xpath后面添加了[0]是因為返回的是只有1個字符串的list,添加[0]是將list提取為字符串,使其簡潔;Network:要在最原始的Network選項卡中定位,而不是Elements中,不然提取不到相關(guān)內(nèi)容;class屬性:p[@class = "star"]/text()表示提取class屬性為"star"的p節(jié)點的文本值;提取屬性值:img[2]/@src':提取img節(jié)點的src屬性值,屬性值后面無需添加'/text()'

運(yùn)行程序,就可成功地提取出所需內(nèi)容,結(jié)果和第一種方法一樣。

以上是第2種提取方法,如果也不太習(xí)慣xpath語法,可以試試下面的第3種方法。

3.3.3. Beautiful Soup + css選擇器

Beautiful Soup 同lxml一樣,是一個非常強(qiáng)大的python解析庫,可以從HTML或XML文件中提取效率非常高。關(guān)于它的用法,可參考下面的教程:

https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/

css選擇器選是一種模式,用于選擇需要添加樣式的元素,使用它的語法同樣能夠快速定位到所需節(jié)點,然后提取相應(yīng)內(nèi)容。使用方法可參考下面的教程:

http://www.w3school.com.cn/cssref/css_selectors.asp

下面就利用這種方法進(jìn)行提?。?/p>

1# 3 用beautifulsoup + css選擇器提取

2def parse_one_page3(html):

3 soup = BeautifulSoup(html, 'lxml')

4 # print(content)

5 # print(type(content))

6 # print('------------')

7 items = range(10)

8 for item in items:

9 yield{

10

11 'index': soup.select('dd i.board-index')[item].string,

12 # iclass節(jié)點完整地為'board-index board-index-1',寫board-index即可

13 'thumb': get_thumb(soup.select('a > img.board-img')[item]["src"]),

14 # 表示a節(jié)點下面的class = board-img的img節(jié)點,注意瀏覽器eelement里面是src節(jié)點,而network里面是src節(jié)點,要用這個才能正確返回值

15

16 'name': soup.select('.name a')[item].string,

17 'star': soup.select('.star')[item].string.strip()[3:],

18 'time': get_release_time(soup.select('.releasetime')[item].string.strip()[5:]),

19 'area': get_release_area(soup.select('.releasetime')[item].string.strip()[5:]),

20 'score': soup.select('.integer')[item].string + soup.select('.fraction')[item].string

21

22 }

運(yùn)行上述程序,結(jié)果同第1種方法一樣。

3.3.4. Beautiful Soup + find_all函數(shù)提取

Beautifulsoup除了和css選擇器搭配,還可以直接用它自帶的find_all函數(shù)進(jìn)行提取。

find_all,顧名思義,就是查詢所有符合條件的元素,可以給它傳入一些屬性或文本來得到符合條件的元素,功能十分強(qiáng)大。

它的API如下:

1find_all(name , attrs , recursive , text , **kwargs)

常用的語法規(guī)則如下:?soup.find_all(name='ul'): 查找所有ul節(jié)點,ul節(jié)點內(nèi)還可以嵌套; li.string和li.get_text():都是獲取li節(jié)點的文本,但推薦使用后者;soup.find_all(attrs={'id': 'list-1'})):傳入 attrs 參數(shù),參數(shù)的類型是字典類型,表示查詢?id?為?list-1?的節(jié)點;常用的屬性比如 id、class 等,可以省略attrs采用更簡潔的形式,例如:soup.find_all(id='list-1') soup.find_all(class_='element')

根據(jù)上述常用語法,可以提取網(wǎng)頁中所需內(nèi)容:

1def parse_one_page4(html):

2 soup = BeautifulSoup(html,'lxml')

3 items = range(10)

4 for item in items:

5 yield{

6

7 'index': soup.find_all(class_='board-index')[item].string,

8 'thumb': soup.find_all(class_ = 'board-img')[item].attrs['src'],

9 # 用.get('src')獲取圖片src鏈接,或者用attrs['src']

10 'name': soup.find_all(name = 'p',attrs = {'class' : 'name'})[item].string,

11 'star': soup.find_all(name = 'p',attrs = {'class':'star'})[item].string.strip()[3:],

12 'time': get_release_time(soup.find_all(class_ ='releasetime')[item].string.strip()[5:]),

13 'area': get_release_time(soup.find_all(class_ ='releasetime')[item].string.strip()[5:]),

14 'score':soup.find_all(name = 'i',attrs = {'class':'integer'})[item].string.strip() + soup.find_all(name = 'i',attrs = {'class':'fraction'})[item].string.strip()

15

16 }

以上就是4種不同的內(nèi)容提取方法。

3.4. 數(shù)據(jù)存儲

上述輸出的結(jié)果為字典格式,可利用csv包的DictWriter函數(shù)將字典格式數(shù)據(jù)存儲到csv文件中。

1# 數(shù)據(jù)存儲到csv

2def write_to_file3(item):

3 with open('貓眼top100.csv', 'a', encoding='utf_8_sig',newline='') as f:

4 # 'a'為追加模式(添加)

5 # utf_8_sig格式導(dǎo)出csv不亂碼

6 fieldnames = ['index', 'thumb', 'name', 'star', 'time', 'area', 'score']

7 w = csv.DictWriter(f,fieldnames = fieldnames)

8 # w.writeheader()

9 w.writerow(item)

然后修改一下main()方法:

1def main():

2 url = 'http://maoyan.com/board/4?offset=0'

3 html = get_one_page(url)

4

5 for item in parse_one_page(html):

6 # print(item)

7 write_to_csv(item)

8

9

10if __name__ == '__main__':

11 main()

結(jié)果如下圖:

再將封面的圖片下載下來:

1def download_thumb(name, url,num):

2 try:

3 response = requests.get(url)

4 with open('封面圖/' + name + '.jpg', 'wb') as f:

5 f.write(response.content)

6 print('第%s部電影封面下載完畢' %num)

7 print('------')

8 except RequestException as e:

9 print(e)

10 pass

11 # 不能是w,否則會報錯,因為圖片是二進(jìn)制數(shù)據(jù)所以要用wb

3.5. 分頁爬取

上面完成了一頁電影數(shù)據(jù)的提取,接下來還需提取剩下9頁共90部電影的數(shù)據(jù)。對網(wǎng)址進(jìn)行遍歷,給網(wǎng)址傳入一個offset參數(shù)即可,修改如下:

1def main(offset):

2 url = 'http://maoyan.com/board/4?offset=' + str(offset)

3 html = get_one_page(url)

4

5 for item in parse_one_page(html):

6 # print(item)

7 write_to_csv(item)

8

9

10if __name__ == '__main__':

11 for i in range(10):

12 main(offset = i*10)

這樣就完成了所有電影的爬取。結(jié)果如下:

4. 可視化分析

俗話說“文不如表,表不如圖”。下面根據(jù)excel的數(shù)據(jù)結(jié)果,進(jìn)行簡單的數(shù)據(jù)可視化分析,并用圖表呈現(xiàn)。

4.1. 電影評分最高top10

首先,想看一看評分最高的前10部電影是哪些?

程序如下:

1import pandas as pd

2import matplotlib.pyplot as plt

3import pylab as pl #用于修改x軸坐標(biāo)

4

5plt.style.use('ggplot') #默認(rèn)繪圖風(fēng)格很難看,替換為好看的ggplot風(fēng)格

6fig = plt.figure(figsize=(8,5)) #設(shè)置圖片大小

7colors1 = '#6D6D6D' #設(shè)置圖表title、text標(biāo)注的顏色

8

9columns = ['index', 'thumb', 'name', 'star', 'time', 'area', 'score'] #設(shè)置表頭

10df = pd.read_csv('maoyan_top100.csv',encoding = "utf-8",header = None,names =columns,index_col = 'index') #打開表格

11# index_col = 'index' 將索引設(shè)為index

12

13df_score = df.sort_values('score',ascending = False) #按得分降序排列

14

15name1 = df_score.name[:10] #x軸坐標(biāo)

16score1 = df_score.score[:10] #y軸坐標(biāo)

17plt.bar(range(10),score1,tick_label = name1) #繪制條形圖,用range()能搞保持x軸正確順序

18plt.ylim ((9,9.8)) #設(shè)置縱坐標(biāo)軸范圍

19plt.title('電影評分最高top10',color = colors1) #標(biāo)題

20plt.xlabel('電影名稱') #x軸標(biāo)題

21plt.ylabel('評分') #y軸標(biāo)題

22

23# 為每個條形圖添加數(shù)值標(biāo)簽

24for x,y in enumerate(list(score1)):

25 plt.text(x,y+0.01,'%s' %round(y,1),ha = 'center',color = colors1)

26

27pl.xticks(rotation=270) #x軸名稱太長發(fā)生重疊,旋轉(zhuǎn)為縱向顯示

28plt.tight_layout() #自動控制空白邊緣,以全部顯示x軸名稱

29# plt.savefig('電影評分最高top10.png') #保存圖片

30plt.show()

結(jié)果如下圖:

可以看到:排名最高的分別是兩部國產(chǎn)片"霸王別姬"和"大話西游",其他還包括"肖申克的救贖"、"教父"等。

嗯,還好基本上都看過。

4.2. 各國家的電影數(shù)量比較

然后,想看看100部電影都是來自哪些國家?

程序如下:

1area_count = df.groupby(by = 'area').area.count().sort_values(ascending = False)

2

3# 繪圖方法1

4area_count.plot.bar(color = '#4652B1') #設(shè)置為藍(lán)紫色

5pl.xticks(rotation=0) #x軸名稱太長重疊,旋轉(zhuǎn)為縱向

6

7

8# 繪圖方法2

9# plt.bar(range(11),area_count.values,tick_label = area_count.index)

10

11for x,y in enumerate(list(area_count.values)):

12 plt.text(x,y+0.5,'%s' %round(y,1),ha = 'center',color = colors1)

13plt.title('各國/地區(qū)電影數(shù)量排名',color = colors1)

14plt.xlabel('國家/地區(qū)')

15plt.ylabel('數(shù)量(部)')

16plt.show()

17# plt.savefig('各國(地區(qū))電影數(shù)量排名.png')

結(jié)果如下圖:

可以看到,除去網(wǎng)站自身沒有顯示國家的電影以外,上榜電影被10個國家/地區(qū)"承包"了。其中,美國以30部電影的絕對優(yōu)勢占據(jù)第1名,其次是8部的日本,韓國第3,居然有7部上榜。

不得不說的是香港有5部,而內(nèi)地一部都沒有。。。

4.3. 電影作品數(shù)量集中的年份

接下來站在漫長的百年電影史的時間角度上,分析一下哪些年份"貢獻(xiàn)了"最多的電影數(shù)量,也可以說是"電影大年"。

1# 從日期中提取年份

2df['year'] = df['time'].map(lambda x:x.split('/')[0])

3# print(df.info())

4# print(df.head())

5

6# 統(tǒng)計各年上映的電影數(shù)量

7grouped_year = df.groupby('year')

8grouped_year_amount = grouped_year.year.count()

9top_year = grouped_year_amount.sort_values(ascending = False)

10

11

12# 繪圖

13top_year.plot(kind = 'bar',color = 'orangered') #顏色設(shè)置為橙紅色

14for x,y in enumerate(list(top_year.values)):

15 plt.text(x,y+0.1,'%s' %round(y,1),ha = 'center',color = colors1)

16plt.title('電影數(shù)量年份排名',color = colors1)

17plt.xlabel('年份(年)')

18plt.ylabel('數(shù)量(部)')

19

20plt.tight_layout()

21# plt.savefig('電影數(shù)量年份排名.png')

22

23plt.show()

結(jié)果如下圖:

可以看到,100部電影來自37個年份。其中2011年上榜電影數(shù)量最多,達(dá)到9部;其次是前一年的7部?;貞浺幌拢菚赫巧洗髮W(xué)的頭兩年,可怎么感覺除了阿凡達(dá)之外,沒有什么其他有印象的電影了。。。

另外,網(wǎng)上傳的號稱"電影史奇跡年"的1994年僅排名第6。這讓我進(jìn)一步對貓眼榜單的權(quán)威性產(chǎn)生了質(zhì)疑。

再往后看,發(fā)現(xiàn)遙遠(yuǎn)的1939和1940年也有電影上榜。那會兒應(yīng)該還是黑白電影時代吧,看來電影的口碑好壞跟外在的技術(shù)沒有絕對的關(guān)系,質(zhì)量才是王道。

4.3.1. 擁有電影作品數(shù)量最多的演員

最后,看看前100部電影中哪些演員的作品數(shù)量最多。

程序如下:

1#表中的演員位于同一列,用逗號分割符隔開。需進(jìn)行分割然后全部提取到list中

2starlist = []

3star_total = df.star

4for i in df.star.str.replace(' ','').str.split(','):

5 starlist.extend(i)

6# print(starlist)

7# print(len(starlist))

8

9# set去除重復(fù)的演員名

10starall = set(starlist)

11# print(starall)

12# print(len(starall))

13

14starall2 = {}

15for i in starall:

16 if starlist.count(i)>1:

17 # 篩選出電影數(shù)量超過1部的演員

18 starall2[i] = starlist.count(i)

19

20starall2 = sorted(starall2.items(),key = lambda starlist:starlist[1] ,reverse = True)

21

22starall2 = dict(starall2[:10]) #將元組轉(zhuǎn)為字典格式

23

24# 繪圖

25x_star = list(starall2.keys()) #x軸坐標(biāo)

26y_star = list(starall2.values()) #y軸坐標(biāo)

27

28plt.bar(range(10),y_star,tick_label = x_star)

29pl.xticks(rotation = 270)

30for x,y in enumerate(y_star):

31 plt.text(x,y+0.1,'%s' %round(y,1),ha = 'center',color = colors1)

32

33plt.title('演員電影作品數(shù)量排名',color = colors1)

34plt.xlabel('演員')

35plt.ylabel('數(shù)量(部)')

36plt.tight_layout()

37plt.show()

38# plt.savefig('演員電影作品數(shù)量排名.png')

結(jié)果如下圖:

張國榮排在了第一位,這是之前沒有猜到的。其次是梁朝偉和星爺,再之后是布拉德·皮特。驚奇地發(fā)現(xiàn),前十名影星中,香港影星居然占了6位。有點嚴(yán)重懷疑這是不是香港版的top100電影。。。

對張國榮以7部影片的巨大優(yōu)勢雄霸榜單第一位感到好奇,想看看是哪7部電影。

1df['star1'] = df['star'].map(lambda x:x.split(',')[0]) #提取1號演員

2df['star2'] = df['star'].map(lambda x:x.split(',')[1]) #提取2號演員

3star_most = df[(df.star1 == '張國榮') | (df.star2 == '張國榮')][['star','name']].reset_index('index')

4# |表示兩個條件或查詢,之后重置索引

5print(star_most)

可以看到包括排名第1的"霸王別姬"、第17名的"春光乍泄"、第27名的"射雕英雄傳之東成西就"等。

突然發(fā)現(xiàn),好像只看過"英雄本色"。。。有時間,去看看他其他的作品。

1 index star name

20 1 張國榮,張豐毅,鞏俐 霸王別姬

31 17 張國榮,梁朝偉,張震 春光乍泄

42 27 張國榮,梁朝偉,張學(xué)友 射雕英雄傳之東成西就

53 37 張國榮,梁朝偉,劉嘉玲 東邪西毒

64 70 張國榮,王祖賢,午馬 倩女幽魂

75 99 張國榮,張曼玉,劉德華 阿飛正傳

86 100 狄龍,張國榮,周潤發(fā) 英雄本色

由于數(shù)據(jù)量有限,故僅作了上述簡要的分析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容