Python爬蟲一:抓取豆瓣電影Top250

環境:Windows7 +Python3.6+Pycharm2017

目標:抓取豆瓣電影Top 250,保存電影封面到本地,保存電影的基本信息(片名、導演、主演、時間、評分、評價人數、引言)到txt文本。

豆瓣電影Top250應該是屬於最容易抓取的靜態網頁類型,直接用python的urllib庫發送請求,即可獲得瀏覽器上看到的所有信息。不需要登錄,也沒有動態加載信息。

一、思路分析

用chrome打開豆瓣電影Top250頁面, https://movie.douban.com/top250。如下圖第一部電影,肖申克的救贖,電影名稱、導演、主演、年份、評分、評價人數這些信息是我們需要的。我們用瀏覽器或者python向瀏覽器發送請求的時候,返回的是html代碼,我們平時用瀏覽器瀏覽網頁看到的這些圖文並茂的規整的頁面其實是html代碼在經過瀏覽器渲染後的結果。所以我們需要找到要抓取信息在html代碼中的位置。這就叫html解析,解析的工具有很多。比如:正則表達式、Beautifulsoup、Xpath、css等,這裏採用xpath方法。

    如何找到信息在html中的位置呢,首先鼠標右鍵檢查,打開當前網頁的html代碼。然後先單擊箭頭1處的箭頭,把鼠標移動到你要查找的信息上,如箭頭2處的電影名:肖申克的救贖 ,右邊就會顯示你點擊信息在html代碼中的位置(箭頭3)。一個網頁的html代碼全部打開看上去會非常的繁多,其實html代碼是一層一層結構化的,非常規整的。每一對尖括號包起來的是一個標籤,比如箭頭3的<span> ......</span>,這就是一個span標籤。span叫標籤名,class="title"是標籤的屬性,“肖申克的救贖”是標籤的內容。標籤span在html代碼中的完整路徑應該是:

body/div[@id="wrapper"]/div[@id="content"]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]。。。用xpath查找元素就是按照路徑一層層找下去,[@id="wrapper"]表示查找的標籤的屬性,用標籤加上屬性,我們可以更方便的定位,不用從頭找到尾。div[1]、span[1]表示要查找的是該標籤下的第1個div標籤,第1個span標籤。找到span標籤可以用方法span[1]/text()取出其中的內容,pan[1]/@class可以取出屬性值。

    電影封面的下載,只要找到圖片的鏈接地址,就可以調用urllib庫中的函數urllib.request.urlretrieve()直接下載。找到圖片鏈接的方法和上面一樣,把鼠標移動到封面上,右邊就會顯示鏈接的位置。

    每一頁網址的變化規律,一頁可以顯示25部電影,就是說這250部電影一共有10頁。觀察前幾頁的網址很容易發現規律:就是start後面跟的參數變化,等於(頁數-1)*25,而且發現後面的filter去掉也不影響。

第一頁:https://movie.douban.com/top250
第二頁:https://movie.douban.com/top250?start=25&filter=
第三頁:https://movie.douban.com/top250?start=50&filter=


二、代碼實現

先用urllib發送請求,獲得返回的源代碼html。返回的html是字符串格式,需要用tree.HTML轉化成xpath能處理的對象。觀察html代碼,每一個<li> ...</li>,標籤剛好對應一部電影,所以我們先定位到每一個li標籤,在對每一個li標籤解析獲得這個電影的各個信息。

data_title ---電影名稱
data_info  ---電影信息(導演、主演、上映時間)
data_quote ---電影引言
data_score ---電影評分
data_num   ---電影評論人數
data_picurl---電影封面鏈接

完整代碼如下:

from urllib import request
from lxml import etree
#構造函數,抓取第i頁信息
def crow(i):
    #  構造第i頁的網址
    url='https://movie.douban.com/top250?start='+str(25*i)
    #  發送請求,獲得返回的html代碼並保存在變量html中
    html=request.urlopen(url).read().decode('utf-8')
    #將返回的字符串格式的html代碼轉換成xpath能處理的對象
    html=etree.HTML(html)
    #先定位到li標籤,datas是一個包含25個li標籤的list,就是包含25部電影信息的list
    datas = html.xpath('//ol[@class="grid_view"]/li')
    a=0
    for data in datas:
        data_title=data.xpath('div/div[2]/div[@class="hd"]/a/span[1]/text()')
        data_info=data.xpath('div/div[2]/div[@class="bd"]/p[1]/text()')
        data_quote=data.xpath('div/div[2]/div[@class="bd"]/p[2]/span/text()')
        data_score=data.xpath('div/div[2]/div[@class="bd"]/div/span[@class="rating_num"]/text()')
        data_num=data.xpath('div/div[2]/div[@class="bd"]/div/span[4]/text()')
        data_picurl=data.xpath('div/div[1]/a/img/@src')
        print("No: "+str(i*25+a+1))
        print(data_title)
        #保存電影信息到txt文件,下載封面圖片
        with open('douban250.txt','a',encoding='utf-8')as f:
            #封面圖片保存路徑和文件名
            picname='F:/top250/'+str(i*25+a+1)+'.jpg'
            f.write("No: "+str(i*25+a+1)+'\n')
            f.write(data_title[0]+'\n')
            f.write(str(data_info[0]).strip()+'\n')
            f.write(str(data_info[1]).strip()+'\n')
            #因爲發現有幾部電影沒有quote,所以這裏加個判斷,以免報錯
            if data_quote:
                f.write(data_quote[0]+'\n')
            f.write(data_score[0]+'\n')
            f.write(data_num[0]+'\n')
            f.write('\n'*3)
            #下載封面圖片到本地,路徑爲picname
            request.urlretrieve(data_picurl[0],filename=picname)
        a+=1
for i in range(10):
    crow(i)

三、結果

結果如下圖,還有些問題就是主演的名字不完整,如需完整需要進入每一個電影的詳情頁面。本人也是python新手,這是在CSDN發的第一篇文章,水平一般,如有錯誤望大家指正。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章