天天看點

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中
一.前言

      python作為一個解釋型語言,在資料分析,資料爬取方面有自己的先天優勢,近幾年也正被越來越多的人所使用,本篇文章以一個簡單的資料爬取的例子來幫助大家入門python,相信你會感興趣.同時對于喜歡看電影的小夥伴也是一個福利.

      首先看一下成果,這是我們要爬取的頁面:

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中
py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

      這樣的頁面總共有十頁,每一頁是25個,我們爬取每個電影的名稱,連結,評分等等資訊存儲在excel中,爬取效果如下:

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中
二.總體思路

1.通過url請求,得到對應的html頁面;

2.通過BeautifulSoup取出與電影資訊相關的html代碼,然後通過正規表達式取 出具體的資料

3.将資料存儲至excel表格中.

第一步,擷取html代碼

      我們需要模仿浏覽器向伺服器發送一個url請求,這樣就能得到伺服器的響應,也就是目前頁面的html代碼,通過以下代碼就可以.

# 請求頭中的User-Agent是直接copy浏覽器中的,顯示了浏覽器的型号,進而讓伺服器認為我們是一個浏覽器
header = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"}
html=""
request=urllib.request.Request("https://movie.douban.com/top250?start=",headers=header) #構造請求資料
response = urllib.request.urlopen(request) #發起url請求
html=response.read().decode('utf-8') #用utf-8進行解碼
           

      這樣我們就得到了伺服器響應的html代碼,如下:

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

      因為整個html頁面代碼很多,這裡隻是截取了其中一部分,得到的html代碼應是與直接在浏覽器頁面右鍵單擊–>檢查,得到的源代碼一樣的,如下:

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

補充:其實模仿浏覽器發送url請求本身并不複雜,浏覽器向伺服器發送請求,本質上就是向伺服器發送了這些資料而已.那我們利用代碼也當然可以做到.

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

第二步,篩選具體資料

      我們想要的資料就在這些html代碼中,那我們要篩選出我們想要的資料,這裡首先要利用一個工具類BeautifulSoup,通過浏覽器頁面選取元素我們可以知道,我們想要的資料在一個class='item’的div中

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

      于是借助BeautifulSoup,使用如下代碼即可篩選出與每一個電影資料相關的html代碼.

bs = BeautifulSoup(html,"html.parser") #構造 BeautifulSoup類對象
 items=bs.find_all('div',class_='item'): #該方法會比對出所有的符合内容,傳回一個集合
           

      篩選出的結果如下(其中一個電影的資料):

<div class="item">
                <div class="pic">
                    <em class="">1</em>
                    <a href="https://movie.douban.com/subject/1292052/">
                        <img width="100" alt="肖申克的救贖" src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" class="">
                    </a>
                </div>
                <div class="info">
                    <div class="hd">
                        <a href="https://movie.douban.com/subject/1292052/" class="">
                            <span class="title">肖申克的救贖</span>
                                    <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
                                <span class="other">&nbsp;/&nbsp;月黑高飛(港)  /  刺激1995(台)</span>
                        </a>


                            <span class="playable">[可播放]</span>
                    </div>
                    <div class="bd">
                        <p class="">
                            導演: 弗蘭克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·羅賓斯 Tim Robbins /...<br>
                            1994&nbsp;/&nbsp;美國&nbsp;/&nbsp;犯罪 劇情
                        </p>

                        
                        <div class="star">
                                <span class="rating5-t"></span>
                                <span class="rating_num" property="v:average">9.7</span>
                                <span property="v:best" content="10.0"></span>
                                <span>2075016人評價</span>
                        </div>

                            <p class="quote">
                                <span class="inq">希望讓人自由。</span>
                            </p>
                    </div>
                </div>
            </div>
           

      再之後我們還需要篩選出具體的我們想要的資料,比如說電影名稱,評價等等資訊,這裡使用正規表達式進行篩選,在python需要借助re工具類來使用正則.

      比如現在我們要篩選電影名稱,它在這一句代碼中.

<span class="title">肖申克的救贖</span>

,那我們可以這樣寫,

# ()作為一組,一個整體,比對出來的就是()裡面的内容
name=re.compile(r'<span class="title">(.*)</span>')
#findall方法就是進行比對,找出所有的符合的内容,該方法會傳回一個數組,是以要取第一個
name.findall(item)[0] #item就是使用BeautifulSoup已經篩選出的與電影相關的html代碼.也就是上一張代碼的内容.
           

      其他評價,電影連結等等資訊和篩選電影名稱的代碼,思想是相似的,這裡不再贅述.

第三步,存儲資料.

      我們需要将篩選出的資料存儲到excel中,這裡要用到xlwt工具類,将資料寫入到excel表格中.其實也就是調用對應的方法即可,那怎樣具體指定我們寫入到哪一個單元格當中呢?

      這裡是将整個表格看作一個坐标軸,左上角為原點,坐标為(0,0).那麼下圖中所框住的表格的坐标就是(1,2).

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中

      現在舉例,我們想要在(0,0)單元格寫入hello資料,代碼可以這樣寫;

#建構一個workbook檔案對象,也就是excel檔案對象
workbook= xlwt.Workbook(encoding='utf-8')
#建立工作表對象,也就是worksheet,
sheet = workbook.add_sheet('sheet1')
#寫入資料,第一個是橫坐标,第二個是縱坐标,第三個是寫入的内容
sheet.write(0,0,'hello')
#儲存資料,不儲存的話是在記憶體中,參數就是檔案名稱
workbook.save('test.xls')
           
三.全部代碼

      在實際操作中,我們需要循環處理,分别篩選出每一頁的資料存儲到一個總的數組中,然後将資料儲存,全部代碼如下:

from bs4 import BeautifulSoup    #網頁解析,擷取資料
import re      #正規表達式
import urllib.request,urllib.error  #定制url,擷取網頁資料
import xlwt    #進行excel操作
import sqlite3 #進行資料庫操作

def main():
    # 擷取資料
    baseurl="https://movie.douban.com/top250?start="
    data=getDate(baseurl)
    # 儲存資料
    savePath=".\\豆瓣電影top250.xls"     # .\就表示目前路徑
    saveDate(savePath,data)

#得到指定一個url的網頁的内容
def askUrl(url):
    # 請求頭中的User-Agent是直接copy浏覽器中的,顯示了浏覽器的型号,進而讓伺服器認為我們是一個浏覽器
    header = {'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"}
    html=""
    try:
        request=urllib.request.Request(url,headers=header) #構造請求資料
        response = urllib.request.urlopen(request) #發起url請求
        html=response.read().decode('utf-8')
    except urllib.error.URLError as e:
        if hasattr(e,"code"):       #如果有code屬性,列印出來
            print(e.code)
        if hasattr(e,"reason"):     #如果有reason,列印出來
            print(e.reason)
    return html

#電影名稱
name=re.compile(r'<span class="title">(.*)</span>') # ()作為一組,一個整體,比對出來的就是()裡面的内容
#電影連結
link=re.compile(r'<a href="(.*)" target="_blank" rel="external nofollow" >')
#電影圖檔
img=re.compile(r'<img alt=".*src="(.*) width="100"/>')
#電影評分
mark=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#評分人數
markNum=re.compile(r'<span>(\d*)人評價</span>')
#電影關鍵詞
keyWords=re.compile(r'<span class="inq">(.*)</span>')
#電影詳情
details=re.compile(r'<p class="">(.*?)</p>',re.S)
#re.S是使.包括換行符,這裡必須包括?,就是0次到1次,不然會把其他包含進去.也就是當第一次遇到</p>時就結束,否則就會比對到最後一次遇到<\p>時結束.

def getDate(baseurl):
    totaldata=[]
    for i in range(0,10):
        #擷取資料
        html=askUrl(baseurl+str(i*25))   #循環調用分頁請求,每一頁25個資料
        # 解析資料,大概思路就是通過bs找到大概的html代碼,然後通過re解析具體資料
        bs = BeautifulSoup(html,"html.parser")
        for item in bs.find_all('div',class_='item'):
            data=[]
            item=str(item)
            data.append(name.findall(item)[0])   #添加電影名稱
            data.append(link.findall(item)[0])   #添加電影連結
            data.append(img.findall(item)[0])    #添加電影圖檔
            data.append(mark.findall(item)[0])   #添加電影評分
            data.append(markNum.findall(item)[0]) #添加電影評價人數
            keyWord=keyWords.findall(item)         #電影關鍵句有可能為空,要做處理
            if len(keyWord) != 0:
                keyWord=keyWord[0].replace('。','')
                data.append(keyWord)
            else:
                data.append(' ')
            detail=details.findall(item)  #電影詳情需要去除空格,<div>等等多餘符号
            detail=re.sub(r'<br(\s+)?/>(\s+)?','',detail[0])   #去除<br>,(\s+)? 表示比對任意空格,包括制表符,換行符等
            detail=re.sub(r'/',',',detail)
            data.append(detail.strip())
            totaldata.append(data)
    return totaldata

#儲存資料
def saveDate(savePath,data):
    workbook= xlwt.Workbook(encoding='utf-8', style_compression=1)
    sheet = workbook.add_sheet('豆瓣電影top250',cell_overwrite_ok=True)  #cell_overwrite_ok表示每個單元格的是否可以被覆寫掉
    cal=('電影名稱','電影連結','電影圖檔','電影評分','電影評價人數','電影關鍵句','電影詳情')
    for i in range(0,7):
        sheet.write(0,i,cal[i])
    for index,i in enumerate(data):
        print("儲存第{}行".format(index+1))
        for j in range(0,7):
            sheet.write(index+1,j,i[j])
    workbook.save(savePath)

if __name__ == '__main__':     # 程式的入口
    main()
    print("爬取完畢")
           

如果代碼中有什麼不了解的地方或者說覺得可以改進的地方,都可以評論哦,都會一一回應的.

py:90行代碼教你爬取豆瓣電影top250并存儲到Excel中