先看一下Item Loaders的說明,官網對ItemLoaders的介紹是,如果想要保存單個數據或者對數據執行額外的處理,那將是 Item Loaders發揮作用的地方。
Item Loaders provide a convenient mechanism for populating scraped Items.
Item Loaders are designed to provide a flexible, efficient and easy mechanism for extending and overriding different field parsing rules, either by spider, or by source format (HTML, XML, etc) without becoming a nightmare to maintain.
一句話,ItemLoader提供了一種簡單高效,可擴展的方式來填充字段。
本文重點是在Scrapy中使用ItemLoaders下載圖片,先對比一下Item和ItemLoader。
一、Items使用
Item的作用是把非結構性的數據源(網頁)提取為結構性的數據。Item
對象是種簡單的容器,保存了爬取到得數據。可以理解為對象。
** 1) 聲明定義Item:**
from scrapy import Field,Item
class ImageloadItem(Item):
url = Field()
name = Field()
tags = Field()
image_urls = Field()
images = Field()
Item中沒有不同字段類型(數據類型),字段類型由存入時的數據類型決定。
2) 在Spider中設置字段的值:
item = ImageloadItem()
item['url']= response.url
item['name'] = name #name在之前已提取
item['tag'] = tag #tag在之前已提取
... ....
return item #提交item
當Item在Spider中被收集之后,它將會被傳遞到Item Pipeline,一些組件會按照一定的順序執行對Item的處理。
二、ItemLoader使用
同樣需要定義Item,ItemLoader 用在Spider保存數據。
def parse_item(self, response):
l = ItemLoader(item=ImagetestItem(), response=response)
l.add_xpath('name', '//h2/a/text()')
l.add_xpath('tags', "http://div[@id='maincontent']/div[@class='postmeta clearfix']/div[@class='metaRight']/p")
l.add_xpath('image_urls', "http://div[@id='picture']/p/img/@src", Identity())
## 上面image_urls 提取的是一組圖片的src數據
l.add_value('url', response.url)
return l.load_item() #提交數據到pipeline處理
此處使用Itemloader提交了一組數據,如果使用Item這里應該使用循環,提交單個數據。
PipeIine處理數據
class ImageloadPipeline(object):
def process_item(self, item, spider):
for image_url in item['image_urls']:
print image_url
## 處理下載圖片...
return item
在這里循環處理圖片的下載。
啟用Item Pipeline組件,在settings.py配置:
ITEM_PIPELINES = {'imagetest.pipelines.ImageloadPipeline': 1}
分配給每個類的整型值,確定了他們運行的順序,item按數字從低到高的順序,通過pipeline,通常將這些數字定義在0-1000范圍內。
三、案例 -- 使用Scrapy下載整站圖片
案例為使用Scrapy爬蟲整站抓取妹子圖。http://www.meizitu.com/
1) Scrapy Spider處理流程:
www.meizitu.com 這個站點,頁面分為3類:
- 首頁 ,爬蟲入口,中部是圖片鏈接,下部有分頁信息
- 列表頁,由分頁信息進來,爬蟲獲得后續的url,每個列表頁下部有分頁
- 內容頁,由首頁和列表頁url過來處理,獲得下載圖片的url
2) Spider中的方法:
-
parse()
- 處理首頁圖片url, 調用parse_item()
- 處理首頁上的分頁,獲得下一頁url,調用parse()
- 處理列表頁url, 獲得列表頁上圖片url,調用parse_item;處理頁面上分頁url, 獲得下一頁url,遞歸調用parse()
parse_item()
獲得內容頁上的圖片url,圖片src保存在item loader中。
3) 在pipline中處理圖片下載
with open(file_path, 'wb') as handle:
response = requests.get(image_url, stream=True)
for block in response.iter_content(1024):
if not block:
break
handle.write(block)
另外,防止爬蟲過度頻度訪問網站,在setting.py中設置
DOWNLOAD_DELAY = 0.25 # 250 ms of delay
之前也寫了一篇文章《Python爬蟲框架Scrapy快速入門》 講到圖片下載,沒有用到ItemLoader。大家可以參考。
參考:
- Spider0.25官方文檔
- 網絡代碼《Python使用Scrapy爬取妹子圖》