爬取淘寶商品資訊
阿新 • • 發佈:2019-01-04
我們先來解決一下前置知識,本爬蟲會用到以下庫
- requests 是一個很實用Python的一個很實用的HTTP客戶端,可以滿足如今爬蟲的需要
- json 用於資料的處理
- csv 用於資料的儲存
分析說明
爬取淘寶商品的資訊,資料主要用於分析市場趨勢,從而制定一系列營銷方案。實現功能如下:
- 使用者提供關鍵字,利用淘寶搜尋功能獲取搜尋後的資料
- 獲取商品資訊:標題,價格,銷量,店鋪所在區域
- 資料以檔案格式儲存
功能實現依次體現了爬蟲的開發流程:爬蟲規則->資料清洗->資料儲存。
使用谷歌瀏覽器進入淘寶網站,利用搜索的功能輸入‘四件套’關鍵字,
使用瀏覽器的除錯功能捕捉資訊,如果在響應的HTML中找不到資料,
那麼可能資料是通過Ajax請求後臺的,再通過前端渲染到頁面上去的,
單擊XHR,傳送一個請求,檢視資料請求資訊如下圖所示
接下來,我們單擊Preview檢視該URL的響應資料格式,
發現數據是JSON格式的,商品的標題,價格,銷量,店鋪名稱和店鋪所在地點
分別對應的資料為raw_title,view_price,view_sales,nick,item_loc
我們把它的請求連結拿出來研究一下
https://s.taobao.com/api?_ksTS=1540176287763_226&callback=jsonp227&ajax=true&m=customized&sourceId=tb.index&_input_charset=utf-8&bcoffset=-1&commend=all&suggest=history_1&source=suggest&search_type=item&ssid=s5-e&suggest_query=&spm=a21bo.2017.201856-taobao-item.2&q=四件套&s=36&initiative_id=tbindexz_20170306&imgfile=&wq=&ie=utf8&rn=9e6055e3af9ce03b743aa131279aacfd
我們可以把這個長長的連結簡化一下
https://s.taobao.com/api?callback=jsonp227&m=customized&q=%E5%9B%9B%E4%BB%B6%E5%A5%97&s=36
從簡化後的URL看出,有兩個引數可以動態設定來獲取不同的商品
- q = 四件套 這個是搜尋的關鍵字
- s = 36 這個是頁數設定,
功能實現
根據對網站的分析獲取單個關鍵字搜尋的單頁商品資訊,程式碼如下:
import requests import json url = "https://s.taobao.com/api?callback=jsonp227&m=customized&q=四件套&s=36" r = requests.get(url) response = r.text # 擷取成標準的JSON格式 # 由於Ajax返回的資料是字串格式的餓,在返回的值jsonp227(XXX)中 # XXX部分是JSON格式資料,因此先用字串split()擷取XXX部分, #然後將XXX部分由字串格式轉成JSON格式的資料讀取 response = response.split('(')[1].split(')')[0] # 讀取JSON response_dict = json.loads(response) # 定位到商品資訊列表 response_auctions_info = response_dict['API.CustomizedApi']['itemlist']['auctions']
如果想要獲取多頁資料,可以在上述的程式碼中加入一個迴圈,實現程式碼如下:
for p in range(88):
url = "https://s.taobao.com/api?callback=jsonp227&m=customized&q=四件套&s=%s" % (p)
r = requests.get(url)
# 獲取響應資訊字串
response = r.text
# 轉換成JSON格式
response = response.split('(')[1].split(')')[0]
# 載入資料
response_dict = json.loads(response)
# 商品資訊
response_auctions_info = response_dict['API.CustomizedApi']['itemlist']['auctions']
上述程式碼只能獲取單個關鍵字搜尋的商品資訊,
如果要實現多個關鍵字的功能呢,就可以在上述程式碼中在多加一個迴圈,程式碼如下:
for k in ['四件套','手機殼']:
for p in range(88):
url = "https://s.taobao.com/api?callback=jsonp227&m=customized&q=%s&s=%s" % (k,p)
r = requests.get(url)
response = r.text
response = response.split('(')[1].split(')')[0]
response_dict = json.loads(response)
# 商品資訊
response_auctions_info = response_dict['API.CustomizedApi']['itemlist']['auctions']
資料儲存
我們以CSV檔案的格式儲存資料,我們來定義一個函式:
def get_auctions_info(response_auctions_info,file_name):
with open(file_name,'a',newline='') as csvfile:
# 生成CSV物件,用於寫入CSV檔案
writer = csv.writer(csvfile)
for i in response_auctions_info:
# 判斷是否資料已經記錄
if str(i['raw_title']) not in auctions_distinct:
# 寫入資料
# 分別是商品資訊列表和CSV檔案路徑。
# 但該檔案並沒有對CSV設定表頭,所以在開始獲取資料之前。
# 應該生成對應CSV檔案,並設定其表頭
writer.writerrow([i['raw_title'],i['view_price'],i['view_sales'],i['nick'],i['item_loc']])
auctions_distinct.append(str(i['raw_title']))
csvfile.close()
綜合上述條件,整體程式碼如下:
import requests
import json
import csv
# 定義全域性變數,用於判斷資料是否已經記錄
global auctions_distinct
auctions_distinct = []
def get_auctions_info(response_auctions_info, file_name):
with open(file_name, 'a', newline='') as csvfile:
# 生成csv物件,用於寫入CSV檔案
writer = csv.writer(csvfile)
for i in response_auctions_info:
# 判斷是否資料已經記錄
if str(i['raw_title']) not in auctions_distinct:
# 寫入資料
writer.writerow([i['raw_title'], i['view_price'],i['view_sales'], i['nick'], i['item_loc']])
auctions_distinct.append(str(i['raw_title']))
csvfile.close()
if __name__ == '__main__':
for k in ['四件套', '手機殼']:
# 新建csv檔案,每迴圈一個關鍵字會生成其對應的CSV檔案
file_name = k + '.csv'
with open(file_name, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
# 寫入表頭資訊
writer.writerow(['標題', '價格', '銷量', '店鋪', '區域'])
# 寫完關閉檔案
csvfile.close()
# 迴圈次數可以根據實際自行設定
for p in range(88):
url = 'https://s.taobao.com/api?callback=jsonp227&m=customized&q=%s&s=%s' % (k, p)
r = requests.get(url)
response = r.text
response = response.split('(')[1].split(')')[0]
response_dict = json.loads(response)
response_auctions_info = response_dict['API.CustomizedApi']['itemlist']['auctions']
# 呼叫函式get_auctions_info寫入商品資訊
get_auctions_info(response_auctions_info, file_name)
print('獲取資料量為:' + len(auctions_distinct))
總結
- 去除無用的連結的引數,簡化連結
- 分析URL的請求引數含義以及響應內容的資料規律
- 資料儲存的去重判斷