先看一下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', "//div[@id='maincontent']/div[@class='postmeta clearfix']/div[@class='metaRight']/p")
l.add_xpath('image_urls', "//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爬取妹子图》