快速收集信息,Python爬蟲教你一招爬取豆瓣Top250信息!


隨着科技不斷發展,互聯網已經進入了大數據時代。

我們過去只能通過報刊雜志、電視廣播獲取到有限的信息,而現在,互聯網上的海量數據,讓我們享受到了信息自由。

但是,我們獲取到了海量的信息同時,也帶來了大量的垃圾信息。

所以必須要通過一些技術手段進行收集、整理、分析、篩選,然后才能獲取到對我們有用的相關內容。
而這個技術手段,就叫網絡爬蟲技術。

前兩天老鐵跟我吐槽,他的老板突然要他收集豆瓣電影Top250榜單上的電影詳細信息,然后做成Excel表格。

他當時聽到這個消息很崩潰,他的本職工作不是這一方面,只是被臨時拉來頂班。他當時跟我說這么多的信息,復制粘貼也需要很多時間,在他花費了一大把時間,但是並沒有什么成果。

所以他來問我:你們程序員有沒有什么黑科技,可以快速收集網頁信息。

我當時靈光一閃,這用Python爬蟲技術不就可以很快實現。用幾行代碼快速獲取信息,生成Excel表格。

在這里插入圖片描述


爬蟲案例講解

爬蟲可以爬取的內容有很多,比如房價、房源數據,股票信息或者是購物網上的一些商品信息,就是大部分網頁上有的信息都可以爬取下來,尤其對於信息收集工作者來說,簡直是福音。

對於初學者來說,復雜的爬蟲案例可能會有困難,所以我教大家簡單的網頁信息爬取,以豆瓣電影TOP250榜單為例,把電影信息爬取下來。話不多說,往下看↓ ↓ ↓

這是爬取的結果:
在這里插入圖片描述

我這邊用的是pychram 運行的,最開始就是導入庫和模塊

# -*- codeing = utf-8 -*-

from bs4 import BeautifulSoup  # 網頁解析,獲取數據

import re  # 正則表達式,進行文字匹配

import urllib.request, urllib.error  # 指定URL,獲取網頁數據

import xlwt  # 進行excel操作

#import sqlite3  # 進行SQLite數據庫操作

開頭的這個是設置編碼為utf-8 ,寫在開頭,防止亂碼。

本次爬蟲能用到的就是這些庫,后面也都加了注釋,我這里主要講存儲在Excel里,也可以用數據庫操作。

我們主要爬取的是
https://movie.douban.com/top250 這個網址,它跳轉的是以這個網頁,我們主要是要爬取左側電影的信息。

在這里插入圖片描述

爬取網頁大致分三步

1.獲取數據

2.解析內容

3.保存數據

在這里插入圖片描述


(一)獲取數據

def main():
    baseurl = "https://movie.douban.com/top250?start="  #要爬取的網頁鏈接
    # 1.爬取網頁
    datalist = getData(baseurl)

baseurl 就是我們要爬取的網頁鏈接,下面就是調用getData(baseurl)

# 爬取網頁
def getData(baseurl):
    datalist = []  #用來存儲爬取的網頁信息
    for i in range(0, 10):  # 調用獲取頁面信息的函數,10次
        url = baseurl + str(i * 25)
        html = askURL(url)
        

這里為什么要調用10次?因為豆瓣電影Top250,頁面包括250條電影數據,分10頁,每頁25條。每頁URL的不同之處:最后的頁面數值=(頁面數-1)25,所以我們需要訪問頁面10次,2510=250。

然后就請求網頁,Python一般用urllib2庫獲取頁面

# 得到指定一個URL的網頁內容
def askURL(url):
    head = {  # 模擬瀏覽器頭部信息,向豆瓣服務器發送消息
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122  Safari / 537.36"
    }
    # 用戶代理,表示告訴豆瓣服務器,我們是什么類型的機器、瀏覽器(本質上是告訴瀏覽器,我們可以接收什么水平的文件內容)

    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html
  • 對每一個頁面,調用askURL函數獲取頁面內容。

  • 定義一個獲取頁面的函數askURL, 傳入一個urI參數,表示網址,如https:/ /movie.douban.com/ top250?start=0。

  • urllib2.Request生成請求;;urllib2.urlopen發送請求獲取響應; read 獲取頁面內容。

  • 在訪問頁面時經常會出現錯誤,為了程序正常運行,加入異常捕獲try...except...語句。不然可能會出現這樣的錯誤代碼↓

418 I’m a teapotThe HTTP 418 I’m a teapot client error response code indicates that
the server refuses to brew coffee because it is a teapot. This error
is a reference to Hyper Text Coffee Pot Control Protocol which was an
April Fools’ joke in 1998.

翻譯為:HTTP 418 I‘m a teapot客戶端錯誤響應代碼表示服務器拒絕煮咖啡,因為它是一個茶壺。這個錯誤是對1998年愚人節玩笑的超文本咖啡壺控制協議的引用。

其實就是被網站認出來是爬蟲,所以需要掩飾一下
在這里插入圖片描述


(二)解析內容

接下來就是逐一解釋數據

# 2.逐一解析數據
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串
            data = []  # 保存一部電影所有信息
            item = str(item)
            link = re.findall(findLink, item)[0]  # 通過正則表達式查找

在這里插入圖片描述

主要是通正則表達式查找。

正則表達式

正則表達式,通常被用來檢索、替換那些符合某個模式(規則)的文本。

正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一-些特定字符及這些特定字符的組合,組成一個"規則字符串”, 這個"規則字符串”用來表達對字符串的一種過濾邏輯。Python中使用re模塊操作正則表達式。

#影片詳情連接的規則
findLink = re.compile(r'<a href="(.*?)">')  # 創建正則表達式對象,影片詳情鏈接的規則

#影片圖片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) #re.S 讓換行符包含在字符中

#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')

#影片評分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')

#評價人數
findJudge = re.compile(r'<span>(\d*)人評價</span>')

#一句話簡介
findInq = re.compile(r'<span class="inq">(.*)</span>')

#影片相關內容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)

然后應用規則找到我們所需要的內容

 #影片詳情連接
            link = re.findall(findLink, item)[0]       # re庫用來通過正則表達式查找指定的字符串
            data.append(link)                          #添加鏈接

            imgSrc = re.findall(findImgSrc, item)[0]
            data.append(imgSrc)                        #添加圖片

            titles = re.findall(findTitle, item)       #片名可能只有中文名沒有外文名
            if (len(titles) == 2):
                ctitle = titles[0]                     #添加中文名
                data.append(ctitle)
                otitle = titles[1].replace("/", "")    #去掉無關字符
                data.append(otitle)                    #添加外文名
            else:
                data.append(titles[0])
                data.append(' ')                       #如果沒有外文名就留空

            rating = re.findall(findRating, item)[0]
            data.append(rating)                        #添加評分

            judgeNum = re.findall(findJudge, item)[0]
            data.append(judgeNum)                      #添加評分人數

            inq = re.findall(findInq, item)
            if len(inq) != 0:
                inq = inq[0].replace("。", "")         #去掉句號
                data.append(inq)                       #添加一句話簡介
            else:
                data.append(" ")

            bd = re.findall(findBd, item)[0]          #電影詳細信息
            bd = re.sub('<br(\s+)?/>(\s+)?', "", bd)  #去掉<br/>
            # bd = re.sub('/', "", bd)
            data.append(bd.strip())                   #去掉空格

            datalist.append(data)                     #把處理好的電影信息放入datalist

    return datalist

在這里插入圖片描述


(三)保存數據

最后就是將獲取到的內容保存到Excel里面

# 保存數據到表格
def saveData(datalist,savepath):
    print("save.......")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0) #創建workbook對象
    sheet = book.add_sheet('豆瓣電影Top250', cell_overwrite_ok=True) #創建工作表
    col = ("電影詳情鏈接","海報圖片鏈接","影片中文名","影片外文名","豆瓣評分","評價人數","一句話簡介","詳細信息")
    for i in range(0,8):
        sheet.write(0,i,col[i])  #列名
    for i in range(0,250):
        # print("第%d條" %(i+1))       #輸出語句,用來測試
        data = datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])  #數據
    book.save(savepath) #保存

最后運行之后在左側會出現一個這樣的文件:

在這里插入圖片描述

打開可以看到就是我們獲取到的結果:

在這里插入圖片描述

得到我們想要的結果后,稍微調整以下就可以交給領導了,詳細又清晰。我教給老鐵這種方法后(從來沒有接觸過代碼的老鐵都學會了),他都開心瘋了~

在這里插入圖片描述


最后附上我所有的源代碼

# -*- codeing = utf-8 -*-
from bs4 import BeautifulSoup  # 網頁解析,獲取數據
import re  # 正則表達式,進行文字匹配
import urllib.request, urllib.error  # 指定URL,獲取網頁數據
import xlwt  # 進行excel操作



#影片詳情連接的規則
findLink = re.compile(r'<a href="(.*?)">')  # 創建正則表達式對象,影片詳情鏈接的規則

#影片圖片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) #re.S 讓換行符包含在字符中

#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')

#影片評分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')

#評價人數
findJudge = re.compile(r'<span>(\d*)人評價</span>')

#一句話簡介
findInq = re.compile(r'<span class="inq">(.*)</span>')

#影片相關內容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)



def main():
    baseurl = "https://movie.douban.com/top250?start="  #要爬取的網頁鏈接
    # 1.爬取網頁
    datalist = getData(baseurl)
    savepath = "豆瓣電影Top250.xls"    #當前目錄新建XLS,存儲進去
  
    # 3.保存數據
    #saveData(datalist,savepath)      
   

# 爬取網頁
def getData(baseurl):
    datalist = []  #用來存儲爬取的網頁信息
    for i in range(0, 10):  # 調用獲取頁面信息的函數,10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存獲取到的網頁源碼
        # 2.逐一解析數據
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串,形成列表
            data = []  # 保存一部電影所有信息
            item = str(item)
            #影片詳情連接
            link = re.findall(findLink, item)[0]       # re庫用來通過正則表達式查找指定的字符串
            data.append(link)                          #添加鏈接

            imgSrc = re.findall(findImgSrc, item)[0]
            data.append(imgSrc)                        #添加圖片

            titles = re.findall(findTitle, item)       #片名可能只有中文名沒有外文名
            if (len(titles) == 2):
                ctitle = titles[0]                     #添加中文名
                data.append(ctitle)
                otitle = titles[1].replace("/", "")    #去掉無關字符
                data.append(otitle)                    #添加外文名
            else:
                data.append(titles[0])
                data.append(' ')                       #如果沒有外文名就留空

            rating = re.findall(findRating, item)[0]
            data.append(rating)                        #添加評分

            judgeNum = re.findall(findJudge, item)[0]
            data.append(judgeNum)                      #添加評分人數

            inq = re.findall(findInq, item)
            if len(inq) != 0:
                inq = inq[0].replace("。", "")         #去掉句號
                data.append(inq)                       #添加一句話簡介
            else:
                data.append(" ")

            bd = re.findall(findBd, item)[0]          #電影詳細信息
            bd = re.sub('<br(\s+)?/>(\s+)?', "", bd)  #去掉<br/>
            # bd = re.sub('/', "", bd)
            data.append(bd.strip())                   #去掉空格

            datalist.append(data)                     #把處理好的電影信息放入datalist

    return datalist


# 得到指定一個URL的網頁內容
def askURL(url):
    head = {  # 模擬瀏覽器頭部信息,向豆瓣服務器發送消息
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122  Safari / 537.36"
    }
    # 用戶代理,表示告訴豆瓣服務器,我們是什么類型的機器、瀏覽器(本質上是告訴瀏覽器,我們可以接收什么水平的文件內容)

    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html


# 保存數據到表格
def saveData(datalist,savepath):
    print("save.......")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0) #創建workbook對象
    sheet = book.add_sheet('豆瓣電影Top250', cell_overwrite_ok=True) #創建工作表
    col = ("電影詳情鏈接","圖片鏈接","影片中文名","影片外國名","評分","評價數","概況","相關信息")
    for i in range(0,8):
        sheet.write(0,i,col[i])  #列名
    for i in range(0,250):
        # print("第%d條" %(i+1))       #輸出語句,用來測試
        data = datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])  #數據
    book.save(savepath) #保存

if __name__ == "__main__":  # 當程序執行時
    # 調用函數
     main()
     print("爬取完畢!")

這樣我們的爬蟲就爬取完畢了,我這里只是以豆瓣榜單為例,這個方法對於爬取其他網頁也同樣適用。這樣做信息收集是特別方便,會大大提高工作效率。

有問題的,不懂的可以在評論區提出,或者私信我,看到就會回復。

最后關於兩種存儲方式:存儲到Excel和存儲到sqlite數據庫,兩種存儲方式可以選擇一種。我這里寫的是存儲數據到Excel的,如果需要存儲數據庫源代碼的可以私信我!

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM