1. 程式人生 > 其它 >【網路爬蟲學習】實戰,爬取網頁以及貼吧資料

【網路爬蟲學習】實戰,爬取網頁以及貼吧資料

實戰一

抓取您想要的網頁,並將其儲存至本地計算機。

首先我們對要編寫的爬蟲程式進行簡單地分析,該程式可分為以下三個部分:

  • 拼接 url 地址
  • 傳送請求
  • 將照片儲存至本地

明確邏輯後,我們就可以正式編寫爬蟲程式了。

匯入所需模組

from urllib import request, parse

拼接 URL 地址

定義 URL 變數,拼接 url 地址。程式碼如下所示:

url = 'http://www.baidu.com/s?wd={}'

word = input('請輸入想要搜尋的內容:')
params = parse.quote(word)
full_url = url.format(params)

向URL傳送請求

傳送請求主要分為以下幾個步驟:

  • 建立請求物件-Request
  • 獲取響應物件-urlopen
  • 獲取響應內容-read

程式碼如下所示:

# 重構請求頭
headers = {
    'User-Agent':
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
}
# 建立請求對應
req = request.Request(url=full_url, headers=headers)
# 獲取響應物件
res = request.urlopen(req)
# 獲取響應內容
html = res.read().decode('utf-8')

儲存為本地檔案

把爬取的照片儲存至本地,此處需要使用 Python 程式設計的檔案 IO 操作,程式碼如下:

filename = word + '.html'
with open(filename, 'w', encoding='utf-8') as f:
    f.write(html)

完整程式如下所示:

from urllib import request, parse
# 1.拼url地址
url = 'http://www.baidu.com/s?wd={}'

word = input('請輸入想要搜尋的內容:')
params = parse.quote(word)
full_url = url.format(params)
# 2.發請求儲存到本地
# 重構請求頭
headers = {
    'User-Agent':
    'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
}
# 建立請求對應
req = request.Request(url=full_url, headers=headers)
# 獲取響應物件
res = request.urlopen(req)
# 獲取響應內容
html = res.read().decode('utf-8')
# 3.儲存檔案至當前目錄
filename = word + '.html'
with open(filename, 'w', encoding='utf-8') as f:
    f.write(html)

嘗試執行程式,並輸入 RioTianの部落格園,確認搜尋,然後您會在當前的工作目錄中找到“RioTianの部落格園.html”檔案。

函數語言程式設計修改程式

Python 函數語言程式設計可以讓程式的思路更加清晰、易懂。接下來,使用函式程式設計的思想更改上面程式碼。

定義相應的函式,通過呼叫函式來執行爬蟲程式。修改後的程式碼如下所示:

from urllib import request, parse


# 拼接URL地址
def get_url(word):
    url = 'http://www.baidu.com/s?{}'
    # 此處使用urlencode()進行編碼
    params = parse.urlencode({'wd': word})
    url = url.format(params)
    return url


# 發請求,儲存本地檔案
def request_url(url, filename):
    headers = {
        'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'
    }
    # 請求物件 + 響應物件 + 提取內容
    req = request.Request(url=url, headers=headers)
    res = request.urlopen(req)
    html = res.read().decode('utf-8')
    # 儲存檔案至本地
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(html)


# 主程式入口
if __name__ == '__main__':
    word = input('請輸入搜尋內容:')
    url = get_url(word)
    filename = word + '.html'
    request_url(url, filename)

除了使用函數語言程式設計外,也可以使用面向物件的程式設計方法(實戰二),在後續內容中會做相應介紹。

實戰二

抓取百度貼吧(https://tieba.baidu.com/)頁面,比如 Python爬蟲吧、程式設計吧,只抓取貼吧的前 5 個頁面即可。

判斷頁面型別

通過簡單的分析可以得知,待抓取的百度貼吧頁面屬於靜態網頁,分析方法非常簡單:開啟百度貼吧,搜尋“Python爬蟲”,在出現的頁面中複製任意一段資訊,比如“爬蟲需要 http 代理的原因”,然後點選右鍵選擇檢視原始碼,並使用 Ctrl+F 快捷鍵在原始碼頁面搜尋剛剛複製的資料,如下所示:

由上圖可知,頁面內的所有資訊都包含在原始碼頁中,資料並不需要從資料庫另行載入,因此該頁面屬於靜態頁面。

尋找URL變化規律

接下來尋找要爬取頁面的 URL 規律,搜尋“Python爬蟲”後,此時貼吧第一頁的的 url 如下所示:

https://tieba.baidu.com/f?ie=utf-8&kw=python爬蟲&fr=search

點選第二頁,其 url 資訊如下:

https://tieba.baidu.com/f?kw=python爬蟲&ie=utf-8&pn=50

點選第三頁,url 資訊如下:

https://tieba.baidu.com/f?kw=python爬蟲&ie=utf-8&pn=100

重新點選第一頁,url 資訊如下:

https://tieba.baidu.com/f?kw=python爬蟲&ie=utf-8&pn=0

如果還不確定,您可以繼續多瀏覽幾頁。最後您發現 url 具有兩個查詢引數,分別是 kw 和 pn,並且 pn 引數具有規律性,如下所示:

第n頁:pn=(n-1)*50

#引數params
pn=(page-1)*50
params={
         'kw':name,
         'pn':str(pn)
        }

url 地址可以簡寫為:

https://tieba.baidu.com/f?kw=python爬蟲&pn=450

編寫爬蟲程式

下面以類的形式編寫爬蟲程式,並在類下編寫不同的功能函式,程式碼如下所示:

from urllib import request,parse
import time
import random
from ua_info import ua_list #使用自定義的ua池

#定義一個爬蟲類
class TiebaSpider(object):
    #初始化url屬性
    def __init__(self):
        self.url='http://tieba.baidu.com/f?{}'

    # 1.請求函式,得到頁面,傳統三步
    def get_html(self,url):
        req=request.Request(url=url,headers={'User-Agent':random.choice(ua_list)})
        res=request.urlopen(req)
        #windows會存在亂碼問題,需要使用 gbk解碼,並使用ignore忽略不能處理的位元組
        #linux不會存在上述問題,可以直接使用decode('utf-8')解碼
        html=res.read().decode("gbk","ignore")
        return html
    # 2.解析函式,此處程式碼暫時省略,還沒介紹解析模組
    def parse_html(self):
        pass
    # 3.儲存檔案函式
    def save_html(self,filename,html):
        with open(filename,'w') as f:
            f.write(html)
    # 4.入口函式
    def run(self):
        name=input('輸入貼吧名:')
        begin=int(input('輸入起始頁:'))
        stop=int(input('輸入終止頁:'))
        # +1 操作保證能夠取到整數
        for page in range(begin,stop+1):
            pn=(page-1)*50
            params={
                'kw':name,
                'pn':str(pn)
            }
            #拼接URL地址   
            params=parse.urlencode(params)
            url=self.url.format(params)
            #發請求
            html=self.get_html(url)
            #定義路徑
            filename='{}-{}頁.html'.format(name,page)
            self.save_html(filename,html)
            #提示
            print('第%d頁抓取成功'%page)
            #每爬取一個頁面隨機休眠1-2秒鐘的時間
            time.sleep(random.randint(1,2))
#以指令碼的形式啟動爬蟲
if __name__=='__main__': 
    start=time.time()
    spider=TiebaSpider() #例項化一個物件spider
    spider.run() #呼叫入口函式
    end=time.time()
    #檢視程式執行時間
    print('執行時間:%.2f'%(end-start))  #爬蟲執行時間

程式執行後,爬取的檔案將會儲存至 Pycharm 當前工作目錄,輸出結果:

輸入貼吧名:python爬蟲
輸入起始頁:1
輸入終止頁:2
第1頁抓取成功
第2頁抓取成功
執行時間:12.25

以面向物件方法編寫爬蟲程式時,思路簡單、邏輯清楚,非常容易理解,上述程式碼主要包含了四個功能函式,它們分別負責了不同的功能,總結如下:

1) 請求函式

請求函式最終的結果是返回一個 HTML 物件,以方便後續的函式呼叫它。

2) 解析函式

解析函式用來解析 HTML 頁面,常用的解析模組有正則解析模組、bs4 解析模組。通過分析頁面,提取出所需的資料,在後續內容會做詳細介紹。

3) 儲存資料函式

該函式負責將抓取下來的資料保至資料庫中,比如 MySQL、MongoDB 等,或者將其儲存為檔案格式,比如 csv、txt、excel 等。

4) 入口函式

入口函式充當整個爬蟲程式的橋樑,通過呼叫不同的功能函式,實現資料的最終抓取。入口函式的主要任務是組織資料,比如要搜尋的貼吧名、編碼 url 引數、拼接 url 地址、定義檔案儲存路徑。

爬蟲程式結構

用面向物件的方法編寫爬蟲程式時,邏輯結構較為固定,總結如下:

# 程式結構
class xxxSpider(object):
    def __init__(self):
        # 定義常用變數,比如url或計數變數等
       
    def get_html(self):
        # 獲取響應內容函式,使用隨機User-Agent
   
    def parse_html(self):
        # 使用正則表示式來解析頁面,提取資料
   
    def write_html(self):
        # 將提取的資料按要求儲存,csv、MySQL資料庫等
       
    def run(self):
        # 主函式,用來控制整體邏輯
       
if __name__ == '__main__':
    # 程式開始執行時間
    spider = xxxSpider()
    spider.run()

注意:掌握以上程式設計邏輯有助於您後續的學習。

爬蟲程式隨機休眠

在入口函式程式碼中,包含了以下程式碼:

# 每爬取一個頁面隨機休眠1-2秒鐘的時間
time.sleep(random.randint(1,2))

爬蟲程式訪問網站會非常快,這與正常人類的點選行為非常不符。因此,通過隨機休眠可以使爬蟲程式模仿成人類的樣子點選網站,從而讓網站不易察覺是爬蟲訪問網站,但這樣做的代價就是影響程式的執行效率。

聚焦爬蟲是一種執行效率較低的程式,提升其效能,是業界一直關注的問題,由此也誕生了效率較高的 Python 爬蟲框架 Scrapy。

The desire of his soul is the prophecy of his fate
你靈魂的慾望,是你命運的先知。