使用Scrapy ItemLoaders爬取整站图片

先看一下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/

《使用Scrapy ItemLoaders爬取整站图片》 下载的图片

1) Scrapy Spider处理流程:

www.meizitu.com 这个站点,页面分为3类:

  • 首页 ,爬虫入口,中部是图片链接,下部有分页信息
  • 列表页,由分页信息进来,爬虫获得后续的url,每个列表页下部有分页
  • 内容页,由首页和列表页url过来处理,获得下载图片的url

《使用Scrapy ItemLoaders爬取整站图片》 Spider处理流程

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

《使用Scrapy ItemLoaders爬取整站图片》 被限制访问!

之前也写了一篇文章《Python爬虫框架Scrapy快速入门》 讲到图片下载,没有用到ItemLoader。大家可以参考。

参考:

  1. Spider0.25官方文档
  2. 网络代码《Python使用Scrapy爬取妹子图》

github下载

点赞