Python爬取分析豆瓣電影Top250

neverstop_yi發表於2018-09-07

本人最近剛學習python,入門了python爬蟲,第一個練手專案是自己爬取了豆瓣電影Top250榜單,分析一下電影排名、評分、國家、型別之間有什麼關係。剛剛入門,希望一起交流學習。


好,專案最開始需要找到豆瓣電影Top250榜單進行分析連結
這裡寫圖片描述
檢視各頁面的url:
第一頁:https://movie.douban.com/top250?start=0&filter=
第二頁:https://movie.douban.com/top250?start=25&filter=
第三頁:https://movie.douban.com/top250?start=50&filter=
可以看到每一頁為start=等號後的值加25,從此,知道了爬取頁面的url規律。
接下來可以選用BeautifulSoup進行頁面資訊的提取,主要提取電影名字、國家、年份和分數
這裡寫圖片描述
這塊在網上簡單瞭解了一下BeautifulSoup的用法,熟悉一下就可以進行操作測試啦!
程式碼如下:

from bs4 import BeautifulSoup
from lxml import html
import xml
import requests

rank = 1
def write_one_page(soup):
    global rank
    for k in soup.find('div',class_='article').find_all('div',class_='info'):
        name = k.find('div',class_='hd').find_all('span')#電影名字
        score = k.find('div',class_='star').find_all('span')#分數
        inq = k.find('p',class_='quote').find('span')#一句話簡介
        #抓取年份、國家
        actor_infos_html = k.find(class_='bd')
        #strip() 方法用於移除字串頭尾指定的字元(預設為空格)
        actor_infos = actor_infos_html.find('p').get_text().strip().split('\n')
        actor_infos1 = actor_infos[0].split('\xa0\xa0\xa0')
        director = actor_infos1[0][3:]
        role = actor_infos[1]
        year_area = actor_infos[1].lstrip().split('\xa0/\xa0')
        year = year_area[0]
        country = year_area[1]
        type = year_area[2]

        print(rank,name[0].string,score[1].string,inq.string,year,country,type)
        #寫txt
   write_to_file(rank,name[0].string,score[1].string,year,country,type,inq.string)
        rank=rank+1
def write_to_file(rank,name,score,year,country,type,quote):
    with open('Top_250_movie.txt', 'a', encoding='utf-8') as f:
        f.write(str(rank)+';'+str(name)+';'+str(score)+';'+str(year)+';'+str(country)+';'+str(type)+';'+str(quote)+'\n')
        f.close()

if __name__ == '__main__':
    for i in range(10):
        a = I*25
        url = "https://movie.douban.com/top250?start="+str(a)+"&filter="
        f = requests.get(url)               
        soup = BeautifulSoup(f.content, "lxml")
        write_one_page(soup)

至此,將電影的資訊爬取了出來!看到資料一行行爬取出來的時候非常激動!
這裡資料是儲存在了txt檔案中,當時剛入手,對檔案儲存的操作還不是很熟悉,後邊將txt另存成了csv格式的,方便處理。這裡建議直接存成csv格式,更簡單。
所得到的資料:
這裡寫圖片描述
一共是250條資料。接下來就是對資料進行視覺化整理。


第一個,先分析了得分與排名的情況,用matplotlib進行作圖:

最開始得到圖的座標中午一直無法顯示,後來查閱了網上的資料,新增了這樣一行程式碼得到了解決:

plt.rcParams['font.sans-serif']=['Arial Unicode MS']#防止圖片亂碼
import matplotlib.pyplot as plt

    rank = list()
    score = list()
    with open('Top_250_movie.csv','r',encoding = "utf-8") as file:
        reader = csv.DictReader(file)
        rank_str = [row['rank'] for row in reader ]
    with open('Top_250_movie.csv','r',encoding = "utf-8") as file:
        reader = csv.DictReader(file)
        score_str = [row['score'] for row in reader ]

    for x in rank_str:
        rank.append(int(x))
    for y in score_str:
        score.append(float(y))

    plt.gca().invert_yaxis()   #反轉y軸
    plt.style.use('ggplot')
    plt.scatter(score,rank)
    plt.xlabel('score')
    plt.ylabel('rank')
    plt.title('得分和排名')
    plt.show()

得到了下圖:
這裡寫圖片描述
可以看到,電影基本還是呈現得分越高,排名越高。有少許的電影評分較高,但排名不高,這裡邊可能涉及到豆瓣具體的排名演算法,可能還跟評論數,年份有一定的關係?感興趣的可以繼續探討哈哈。


接下來看了一下得分與電影年份的關係,程式碼如下:

year = list()
    score = list()
    with open('Top_250_movie.csv','r',encoding = "utf-8") as file:
        reader = csv.DictReader(file)
        year_str = [row['year'] for row in reader ]
    with open('Top_250_movie.csv','r',encoding = "utf-8") as file:
        reader = csv.DictReader(file)
        score_str = [row['score'] for row in reader ]

    for x in year_str:
        year.append(int(x))
    for y in score_str:
        score.append(float(y))

    plt.style.use('ggplot')
    plt.scatter(year,score)
    plt.xlabel('year')
    plt.ylabel('score')
    plt.title('電影年份')
    plt.show()

得到下圖:
這裡寫圖片描述
可以看到,大部分還是集中在右側,說明觀眾對近30年較為新的電影更喜歡。這也很好理解,與電影基數有關,年代越近,投放到市場的電影也越多,越會產生高質量的電影。但近年來高分電影不多,幾乎沒有9.4分以上的電影。


然後接著又對Top250的電影國家進行了統計,主要是對爬取出電影的country的資料進行計數,有的電影包含多個合作國家,比如既是美國又是英國,這裡均統計了一次。

country = list()

    with open('Top_250_movie.csv','r',encoding = "utf-8") as file:
        reader = csv.DictReader(file)
        country_str =' '.join([row['country'] for row in reader ])
        country_list = country_str.split(' ')

    #統計
    country_set = set(country_list)   #放入set中去除重複資料,得到所有出現的國家
    for item in country_set:
        country.append(country_list.count(item))#計數
    country_set = list(country_set)

    #排序和畫圖
    plt.rcParams['savefig.dpi'] = 300 #圖片畫素
    plt.rcParams['figure.dpi'] = 200 #解析度
    plt.xlabel('country')
    plt.ylabel('count')
    plt.title('國家分析')
    plt.tick_params(labelsize=7)   #字型設定

    mydict = dict(zip(country,country_set))
    mydict_sort = sorted(mydict.items(), key=lambda e:e[0], reverse=True)
    mydict_sort = dict(mydict_sort)
    plt.bar(list(mydict_sort.values()), list(mydict_sort.keys()),color='lightblue')
    plt.show()

得到了下圖:
這裡寫圖片描述
可以看到,美國一家獨大,幾乎超越是其他所有國家的總和,中國大陸排名第七。國產電影還需努力呀!
後邊同理,可以分析電影型別的數量統計:
這裡寫圖片描述
結果可以看到,排名前五的分別是劇情、愛情、喜劇、冒險、驚悚。說明最受歡迎的電影型別還是劇情,愛情類電影。這也符合電影市場,劇情和愛情類電影占多數。


至此,作為我的第一個Python爬蟲專案,就對豆瓣電影Top250的榜單進行了簡單的爬取和分析,作為入手專案個人感覺還是很好的。熟悉了頁面資訊爬取的簡單操作,資料檔案的讀寫,資料的排序和視覺化。很有收穫。當然,由於本人水平極為有限,程式碼還有很大的優化空間,小白期待大佬們的指出改進意見!

相關文章