1. 程式人生 > >python爬蟲學習實踐(一):requests庫和正則表示式之淘寶爬蟲實戰

python爬蟲學習實踐(一):requests庫和正則表示式之淘寶爬蟲實戰

使用requests庫是需要安裝的,requests庫相比urllib 庫來說更高階方便一點,同時與scrapy相比較還是不夠強大,本文主要介紹利用requests庫和正則表示式完成一項簡單的爬蟲小專案----淘寶商品爬蟲。

有關於更多requests庫的使用方法請參考:官方文件

第一步:我們先開啟淘寶網頁

然後搜尋你想爬取的商品資訊,比如:“手機”。然後可以看到各個商品的“商品名稱”、“商品價格”。我們可以爬取手機的名稱和價格,從而達到“貨比三家”的功能。


第二步:滑鼠右鍵點選網頁的空白處,選中“檢視頁面原始碼”,從頁面原始碼中獲取商品名稱和商品價格對應的字典中的key值,從而利用正則表示式來爬取所有商品的資訊。

滑鼠選中“檢視頁面原始碼”後,會出現以下頁面:

HTML格式的原始碼,為了查詢商品名稱和商品價格對應的標籤,也就是字典中的key,我們可以直接複製淘寶某一個商品的名稱或者價格資訊,在頁面原始碼中查詢相對應的資訊。不同的瀏覽器中,按Ctrl+F鍵可進入查詢模式。

現在複製貼上其中一個商品的名稱資訊“榮耀 榮耀9青春版”,得到如下結果:


可以發現其中的鍵值對,“title”是“榮耀 榮耀9青春版”的key,現在我們就得到了商品名稱所對應的標籤,同樣的方法可以查找出商品價格對應的標籤,這裡就不過多闡述,直接給出:


現在得到了商品名稱和價格對應的標籤:“title”和“price”。

如果這樣進行爬蟲的話,只能爬取一個網頁中的商品,如果我們還想爬第二頁,第三頁就要尋找其中每翻一次頁中的網址對應的變化資訊。

先來看看淘寶“手機”商品中第二頁和第三頁中的網址變化資訊。

第二頁:

第三頁:


我們看到,無論是第二頁第三頁,只有最後的“&s=**”部分不一致,同時第二頁對應的s=48,第三頁對應的s=96,可以推測出第i頁的s=48*(i-1),我們只需要把這個url新增到我們的爬取程式上,用for迴圈實現這個url的更新即可。

第三步:進入編寫例項

這裡用python語言編寫程式實現爬蟲功能。

由於需要用到正則表示式和requests庫,所以先引入。

import requests
import re


先定義好一個主函式main,把各個功能模組化,然後再去編寫各個模組的具體程式碼。

def main():
    goods = '手機'
    depth = 3 #爬取3頁
    start_url = 'http://s.taobao.com/search?q=' + goods   #爬取商品的url
    infoList = []  #初始化一個列表,方便把爬取的鍵值對新增到裡面,然後讀取
    for i in range(depth):  #for迴圈更新url
        try:   #處理異常
            url = start_url + '&s=' + str(48*i) #每頁的url
            html = getHTMLText(url) #獲取頁面資訊
            parsePage(infoList, html) #解析獲取的資訊,捕捉商品資訊的鍵值對並且新增到列表中
        except:
            continue
    printGoodsList(infoList)  #列印列表中的鍵值對資訊
主函式寫完了,我們把各功能的模組具體化。

首先是getHTMLText()函式,獲取url頁面的資訊文字:

def getHTMLText(url):
    try:
        r = requests.get(url, timeout=30) #get方法請求url連結,如果超過30秒沒有響應就退出
        r.raise_for_status() #狀態碼,如果是200則請求成功
        r.encoding = r.apparent_encoding #將編碼方式更改為捕捉到的內容的編碼方式,中文網頁一般utf-8
        return r.text
    except:
        return ""
然後是 parsePage( )函式,解析頁面資訊,將商品名稱和商品價格組合成一對鍵值對,然後新增到列表裡。需要用到正則表示式。
def parsePage(ilt, html):
    try:
        plt = re.findall(r'\"price\"\:\"[\d\.]*\"',html) #finfall功能將所有的value數字整合在plt列表
        tlt = re.findall(r'\"title\"\:\".*?\"',html) #將所有title的value整合在tlt列表
        for i in range(len(plt)): #基於列表plt的長度使用for迴圈
            price = eval(plt[i].split(':')[1]) #split用“:”切割key和value;eval可以轉化格式
            title = eval(tlt[i].split(':')[1])
            ilt.append([price , title]) #將商品的價格和名稱作為鍵值對新增到ilt列表
            
    except:
        print("")

最後是列印函式printGoodsList( ),輸出爬取的結果:

def printGoodsList(ilt):
    tplt = "{:4}\t{:8}\t{:16}"
    tplt2 = "{:8}\t{:16}\t{:14}"
    print(tplt2.format("序號", "價格", "商品名稱")) #格式化輸出函式
    count = 0 #序號
    for g in ilt:
        count = count + 1
        print(tplt.format(count, g[0], g[1])) #依次輸出序號,價格,商品名稱
最後執行主函式:main(),檢視結果