之前用四篇很啰嗦的入門級別的文章,帶著大家一起去了解并學習在編寫爬蟲的過程中诈闺,最基本的幾個庫的用法渴庆。
那么今天,我們就正式開始我們的第一篇實戰(zhàn)內(nèi)容雅镊,爬取一整個淘寶店鋪里的所有寶貝的詳情頁襟雷,并且把詳情頁里的寶貝圖片保存下來。我自己剛開了一個小網(wǎng)店仁烹,當時寫出這個爬蟲耸弄,也是真真正正的為我自己服務了一回呢。
在寫之前卓缰,我先把這個爬蟲的代碼分析一下计呈,方便大家在看代碼的時候砰诵,理解整個流程是怎么樣的。
爬蟲框架我一直是使用Scrapy的捌显,在用Scrapy抓取店鋪信息的時候茁彭,因為淘寶的反爬機制,發(fā)現(xiàn)了機器人扶歪,所以獲取不到任何信息理肺,當時我趕著用寶貝圖片,所以我使用了之前介紹的selenium來獲取網(wǎng)頁信息击罪,并且通過我們上一篇介紹的lxml框架來提取信息哲嘲。最主要的庫就是這兩個,那么我針對這個爬蟲媳禁,編寫了一個叫做taobaoShop
的爬蟲類。
之后画切,我們首先進入店鋪的首頁竣稽,抓取首頁所有商品的資料,并用他們的寶貝名霍弹,來生成文件夾毫别,方便存儲對應的詳情圖片,然后爬蟲進入寶貝的詳情頁典格,從詳情頁中提取詳情照片岛宦,并且保存在寶貝名稱對應的文件夾中,在該頁面所有的寶貝爬取完成后耍缴,咱們后檢查是否有分頁砾肺,如果還有下一頁的寶貝,那么進入下一頁的寶貝接著爬防嗡,過程就和剛剛描述的一樣了变汪。
所以我們的淘寶店鋪爬蟲類的初始化代碼是這樣的:
def __init__(self):
"""初始化構造函數(shù)
"""
self.site_url = 'https://shop67309167.taobao.com/?spm=a230r.7195193.1997079397.2.xPZZS0'
self.driver = webdriver.Chrome()
self.sleep_time = 10
self.save_img_path = '/Users/Lix/Documents/tbshop/'
初始化中我們設置了要爬取的店鋪url(這就是我的小店,如果可以的話蚁趁,請各位大佬幫忙點個關注)裙盾,另外是啟動selenium中webdriver的代碼,我用Chrome打開他嫡,靜默的話可以選擇Phantomjs打開番官,另外有個間歇時間,因為爬取的過快钢属,會被淘寶判定為爬蟲徘熔,彈出登錄框,最后的save_img_path
自然就是我保存圖片的路徑了署咽。
在初始化的構造函數(shù)完成之后近顷,我們首先獲取的是淘寶店鋪頁面的網(wǎng)頁信息:
def getPage(self):
"""獲取淘寶店鋪頁面代碼
"""
self.driver.get(self.site_url)
time.sleep(self.sleep_time)
content = self.driver.page_source.encode('utf-8')
print self.driver.title
# 保存html代碼debug
# self.saveHtml('taobaoshop', content)
# 分析該頁面的每個寶貝
self.getItem()
在獲取到店鋪的網(wǎng)頁信息后生音,我們調(diào)用getItem()
函數(shù),獲取每個寶貝的信息:
def getItem(self):
"""爬取當前頁面的每個寶貝窒升,
提取寶貝名字缀遍,價格,標題等信息
"""
html = self.driver.page_source.encode('utf-8')
selector = etree.HTML(html)
itemList = selector.xpath("http://div[@class='item3line1']")
# 循環(huán)遍歷該頁所有商品
index = 0
for item3line1 in itemList:
dl = item3line1.xpath("./dl")
for item in dl:
link = 'https:' + item.xpath("./dt/a/@href")[0]
photo = 'https:' + item.xpath("./dt/a/img/@src")[0]
title = item.xpath("./dd/a/text()")[0]
res = {
'link' : link,
'photo' : photo,
'title' : title
}
# 進入寶貝詳情頁 開始爬取里面的圖片資料
self.getItemDetail(link, '')
# 獲取分頁信息
pagination = selector.xpath("http://div[@class='pagination']/a[contains(@class, 'J_SearchAsync') and contains(@class, 'next')]/@href")
print pagination
print '正在準備切換分頁'
if len(pagination) == 0:
print '沒有下一頁了'
else:
print '加載下一頁內(nèi)容'
self.site_url = 'https:' + pagination[0]
print self.site_url
self.getPage()
在這里饱须,我們看到我們已經(jīng)獲取到了寶貝的鏈接域醇,封面圖,標題蓉媳。并且執(zhí)行了getItemDetail(self, link, save_img_path)
函數(shù)去爬取寶貝的詳情頁了譬挚,最后我們還在循環(huán)結束之后,分析了分頁數(shù)據(jù)酪呻。
那么最后减宣,我們就來看看最關鍵的getItemDetail()
函數(shù),看看是怎么爬取寶貝信息的:
def getItemDetail(self, link, save_img_path):
"""從寶貝的詳情鏈接里 爬取圖片
Arguments:
link {String} -- [寶貝詳情鏈接]
"""
newDriver = webdriver.Chrome()
newDriver.get(link)
time.sleep(self.sleep_time)
print newDriver.title
img_dir_path = self.save_img_path + newDriver.title.encode('utf-8')
if True == self.mkdir(img_dir_path):
print '創(chuàng)建寶貝目錄成功'
html = newDriver.page_source.encode('utf-8')
selector = etree.HTML(html)
# 封面圖
J_ULThumb = selector.xpath("http://div[@class='tb-gallery']/ul/li")
index = 0
for li in J_ULThumb:
# 替換圖片 從50*50 至 400 * 400
if len(li.xpath("./div/a/img/@data-src")) < 1:
continue
small_pic = li.xpath("./div/a/img/@data-src")[0]
common_pic = 'https:' + small_pic.replace('50x50', '400x400')
thumb_title = str('封面圖') + str(index)
print thumb_title
# self.saveImg(img_dir_path, common_pic, thumb_title.decode('utf-8'))
index += 1
# 爬取里面所有圖片
all_img = selector.xpath("http://div[@id='J_DivItemDesc']//descendant::img/@src")
print all_img
index = 0
for img in all_img:
imglink = img
if img.startswith('http') is True:
imglink = img
else:
imglink = 'https:' + img
self.saveImg(img_dir_path, imglink, str(index))
index += 1
newDriver.quit()
注釋都寫在代碼里了玩荠,大家看看就好漆腌,這里有很多地方的代碼不夠優(yōu)雅,那是我當天急著用阶冈,所以后來也沒有去優(yōu)化了闷尿。
在這個核心解析代碼的完成之后,寶貝圖片就已經(jīng)穩(wěn)穩(wěn)的存儲到我們的硬盤上了女坑,可以開箱即用了填具。完整的代碼我也放在了Github上了,如果對您有幫助匆骗,請幫忙star一下劳景。