天天看點

使用python3.7爬取豆瓣電影top250資訊

文章目錄

    • 一、準備工作
    • 1.安裝python3.7
    • 2.安裝爬取豆瓣top250所需包
    • 二、爬取網頁
    • 1.分析網頁
    • 2.爬取網頁
    • 3.資訊篩選
    • 4.複制整個網頁的xpath路徑
    • 5.擷取第一頁每個電影的名字
    • 6.擷取連結
    • 7.評分
    • 8.評價人數
    • 9.排名
    • 10.美化
    • 11用正規表達式re比對星級數中的數字
    • 12.寫入檔案夾

一、準備工作

1.安裝python3.7

打開浏覽器搜尋python,得到如下結果:

使用python3.7爬取豆瓣電影top250資訊

打開圖檔中箭頭網址

或直接通路python官網打開得到以下畫面

使用python3.7爬取豆瓣電影top250資訊

下拉網頁

使用python3.7爬取豆瓣電影top250資訊

選擇自己需要的版本

點選後面的download即可下載下傳。

具體安裝可以參考其他博友文章,這裡不進行過多贅述。

2.安裝爬取豆瓣top250所需包

所需要的包有,jupyter(個人習慣的編輯環境,可以不安裝)、re(正規表達式)、request、lxml、csv

安裝所需包的過程:電腦鍵盤按住win+R,打開控制台,輸入cmd,點選确定或回車啊。

使用python3.7爬取豆瓣電影top250資訊

安裝包的公式為pip install ******

以安裝第一個包為例,輸入pip install jupyter,回車,就可以線上安裝了

使用python3.7爬取豆瓣電影top250資訊

初次安裝會需要一些時間,耐心等待一會,其他的包同理。

二、爬取網頁

1.分析網頁

在此處我們爬取豆瓣電影top250的電影資訊

打開可以看到網頁如下

使用python3.7爬取豆瓣電影top250資訊

我們可以看到本頁隻有25部電影,我們的任務是爬取250部電影,共十頁,分析每一頁的差別,此處打開前三頁和最後一頁的網址對比

第一頁

https://movie.douban.com/top250?start=0&filter=

第二頁

https://movie.douban.com/top250?start=25&filter=

第三頁

https://movie.douban.com/top250?start=50&filter=

最後一頁(第十頁)

https://movie.douban.com/top250?start=225&filter=

由分析我們可以知道,每一頁的網址是差不多的,唯一的差别就是數字的變動,每一頁的數值變化為25,

使用python3.7爬取豆瓣電影top250資訊

除此之外,其餘部分都是一樣的。我們可以用一個for循環數組代碼來實作這個網頁

運用range函數,可以得到十個間隔為25的數組

使用python3.7爬取豆瓣電影top250資訊

此處的是226,而不是225是因為range函數後面的括号為前閉後開區間,即為前可取後不可取,三個數字代表的含義分别為從0開始,到226結束,間隔25.

将start=0改為start=%s,後面跟的%page表示将page函數中的數 值範圍賦予給s,即可一次性構造出十個網頁的連結,代碼如下:

for page in range(0, 226, 25):
    url = 'https://movie.douban.com/top250?start=%s&filter='%page
    print (url)
           

運作代碼可以得到如下圖結果:

使用python3.7爬取豆瓣電影top250資訊

至此,我們已經得到了十個網頁的代碼了。

2.爬取網頁

打開豆瓣網頁,對網頁進行審查,

右擊進入檢查元素,點選網絡(network),再點選所有(All)

對該網頁進行重新整理,下方會出現網頁的組成元素,例如圖檔等

使用python3.7爬取豆瓣電影top250資訊

用箭頭标出來的分别為請求方法和狀态碼,即我們使用的方法為get,傳回的狀态碼為200則為成功,傳回其他數值則不成功。

使用get語句通路浏覽器,得到如下結果,意義為:系統識别出為非正常通路,拒絕傳回值

使用python3.7爬取豆瓣電影top250資訊

此處我們需要僞裝浏覽器,用以躲過網站的識别,首先,講代碼審查中的使用者代理複制過來,構造字典,使用者代理的位置為:

使用python3.7爬取豆瓣電影top250資訊

豆瓣top250中右鍵檢查,notework,all,下拉導航,出現的

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36

即為使用者代理。

import requests
test_url = 'https://movie.douban.com/top250?start=0&filter=' 
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}
requests.get(url=test_url,headers=headers)
           

運作即可得到狀态碼為200的傳回值

使用python3.7爬取豆瓣電影top250資訊

在代碼後加入.text,即可得到以下内容。

使用python3.7爬取豆瓣電影top250資訊

我們可以看到,我們雖然成功得爬取了網頁資料,不過看上去是很雜亂的,我們還需要篩選資料。

我們加上一句代碼

reponse=requests.get(url=test_url,headers=headers).text
#中間一行空格
reponse
           

3.資訊篩選

工具:xpath,re,BeautifulSoup,工具需要提前安裝,安裝教程檢視本文開頭目錄,這裡不做過多贅述。

假如我要從網頁資訊中篩選出“這個殺手不太冷”的電影的名字

使用python3.7爬取豆瓣電影top250資訊
#從lxml包裡面到處etree這個工具
from lxml import etree  
#使用etree解析網頁
html_etree = etree.HTML (reponse)    
#定位 
html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li[4]/div/div[2]/div[1]/a/span[1]/text()')
           

得到如下結果

使用python3.7爬取豆瓣電影top250資訊

網頁檢查中的定位怎麼查找:打開網頁,找到你想查找的資料,點選檢查,在出現的代碼中找到你所選擇的内容,右鍵copy xpath。在xpath後面添加/ text()字尾即可查找。

4.複制整個網頁的xpath路徑

打開網頁,右擊檢查元素,找到每個電影子產品對應的序列代碼,如下圖

使用python3.7爬取豆瓣電影top250資訊

将圖中右側滑鼠選中的位置的xpath路徑複制下來為:

第一個://[@id=“content”]/div/div[1]/ol/li[1]

第二個://[@id=“content”]/div/div[1]/ol/li[2]

第三個://*[@id=“content”]/div/div[1]/ol/li[3]

我們可以分析,每一部電影的結構都大緻相似,隻有最後的數字不一樣。

将上面的代碼表示出來為

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[1]')

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[2]')

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li[3]')

将最後的[數字]删除,即可表示所有的xpath路徑。即

html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li')

可以表示所有的路徑。

使用python3.7爬取豆瓣電影top250資訊

輸入len(li)即可檢視路徑長度

使用python3.7爬取豆瓣電影top250資訊

5.擷取第一頁每個電影的名字

item可以自己命名,name為電影名字,可自己命名

整個語句可了解為,從25個xpath路徑裡面擷取得250個電影,然後再從這250個電影(item)的xpath路徑裡面擷取250個電影名(name)

第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a/span[1]

第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a/span[1]

可看出,兩個連結隻有/li[]中的數字不一樣,

from lxml import etree html_etree = etree.HTML (reponse) li=html_etree.xpath('/html/body/div[3]/div[1]/div/div[1]/ol/li') for item in li: name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()') print(name)

得到如下結果:

使用python3.7爬取豆瓣電影top250資訊

後面加上[0],可以得到

使用python3.7爬取豆瓣電影top250資訊

6.擷取連結

對電影的連結進行分析

第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[1]/a

第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[1]/a

隻有li[]不一樣,其他的都是一樣的,做法同上一個擷取電影名稱

代碼如下:

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')
    print(dy_url)
           

運作:

使用python3.7爬取豆瓣電影top250資訊

7.評分

第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[1]

第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[1]

同理,代碼不一樣

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    print (dy_url)
    rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
    print(rating)

           
使用python3.7爬取豆瓣電影top250資訊

8.評價人數

第一個://[@id=“content”]/div/div[1]/ol/li[1]/div/div[2]/div[2]/div/span[4]

第二個://[@id=“content”]/div/div[1]/ol/li[2]/div/div[2]/div[2]/div/span[4]

同理:

from lxml import etree  
html_etree = etree.HTML (reponse)  
li=html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
for item in li:
    name=item.xpath('./div/div[2]/div[1]/a/span[1]/text()')
    print(name)
    dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    print (dy_url)
    rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
    print(rating)
    content=item.xpath('./div/div[2]/div[2]/div/span[4]/text()')
    print(content)

           
使用python3.7爬取豆瓣電影top250資訊

9.排名

原理同上

使用python3.7爬取豆瓣電影top250資訊

10.美化

輸入’~’*50, 可以加波浪線,50為個數

使用python3.7爬取豆瓣電影top250資訊

11用正規表達式re比對星級數中的數字

如爬取到的星級數為rating5-t或rating4.5-t,但我們隻想要數字,故用正規表達式來比對

re正規表達式文法較複雜,平時可在網上多學習

準備工作:引入re包,import re

我們首先要知道一些關于正規表達式的使用方法,正規表達式替換的方法是.*?替換。

例如:

import re
a = "123人評價"
re.findall('(.*?)人評價', a)
           

則輸出為123.

使用python3.7爬取豆瓣電影top250資訊

這樣輸出的rating分數,還是有一點問題,那就是本來應該是4.5的變為了45,是以我們還需要設定一個條件語句,

if len(rating) == 2:
            star = int(rating) / 10  #int()轉化為數字
        else:
            star = rating
           

意義為當rating長度為2的時候,除以十,當rating長度不為2,就不改變。

12.寫入檔案夾

分為三個步驟,1.建立檔案夾并打開

fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig') writer = csv.writer(fp)

2.寫入

writer.writerow(('排名', '名稱', '連結', '星級', '評分', '評價人數'))
writer.writerow((rank, name, dy_url, star, rating_num, content))
           

3.關閉

插入代碼中,運作即可

使用python3.7爬取豆瓣電影top250資訊

在此處我們看不到檔案,傳回jupyter檔案夾,打開即可看到檔案

使用python3.7爬取豆瓣電影top250資訊

打開可以看到

使用python3.7爬取豆瓣電影top250資訊

至此,我們本次任務完成。

代碼彙總:

import requests, csv, re
from lxml import etree

#設定浏覽器代理,它是一個字典
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'
}

# 建立檔案夾并打開
fp = open("./豆瓣top250.csv", 'a', newline='', encoding = 'utf-8-sig')
writer = csv.writer(fp) #我要寫入
# 寫入内容
writer.writerow(('排名', '名稱', '連結', '星級', '評分', '評價人數'))

for page in range(0, 226, 25): #226
    print ("正在擷取第%s頁"%page)
    url = 'https://movie.douban.com/top250?start=%s&filter='%page
    
    #請求源代碼,向伺服器送出請求,200代表成功,回退對其,Ctrl+]
    reponse = requests.get(url = url, headers = headers).text
    # 快捷鍵運作,Ctrl+Enter
    html_etree = etree.HTML(reponse) # 看成一個篩子,樹狀
    # 過濾
    li = html_etree.xpath('//*[@id="content"]/div/div[1]/ol/li')
    for item in li:
        #排名
        rank = item.xpath('./div/div[1]/em/text()')[0]
        #電影名稱
        name = item.xpath('./div/div[2]/div[1]/a/span[1]/text()')[0]
        #連結
        dy_url = item.xpath('./div/div[2]/div[1]/a/@href')[0]
    #     print (dy_url)
        #評分
        rating = item.xpath('./div/div[2]/div[2]/div/span[1]/@class')[0]
        rating = re.findall('rating(.*?)-t', rating)[0]
        if len(rating) == 2:
            star = int(rating) / 10  #int()轉化為數字
        else:
            star = rating
    #     注釋ctrl+?

        rating_num = item.xpath('./div/div[2]/div[2]/div/span[2]/text()')[0]
        content = item.xpath('./div/div[2]/div[2]/div/span[4]/text()')[0]
        content = re.sub(r'\D', "", content)
#         print (rank, name, dy_url, star, rating_num, content)
        # 寫入内容
        writer.writerow((rank, name, dy_url, star, rating_num, content))
fp.close()
           

通過本次作業,想說的是,自己不夠認真,很多處小錯誤,然後查找錯誤花費了很多時間,一些問題自己無法解決,參考了同學的作業,總的來說需要多從實戰之中擷取經驗。這次辛苦楊友同學老師了。