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(),檢視結果