scrapy爬虫框架之ImagePipeline

Item Pipeline

Item在spider中获取后,将传送到Item Pipeline中,执行对Item的后续处理。每个item pipeline组件实现了简单方法,它们接收item并执行一些操作,决定丢弃item还是让其通过pipeline。

item pipeline的作用:

  • 清理HTML数据
  • 验证爬取的数据(检查item包含的某些字段)
  • 查重
  • 保存将爬取到的数据

当然,你也可以编写自己的item pipeline,不过你需要实现以下方法:

process_item(item,spider)
    每个item pipeline都需要调用该方法,并且返回一个Item对象或者抛出DropItem异常,item被丢弃后将不被pipeline处理。
    参数: item(Item对象)-被爬取的item
           spider(Spider对象)-爬取该是特么的spider

除此之外,还可以实现以下方法:

open_spider(spider):当spider开启时调用。
close_spider(spider):当spider关闭时调用。

ImagePipeline

scrapy用ImagePipeline提供了一种方便的方式下载和存储图片。

自定义ImagePipeline时,最重要的是重载get_media_requests(self,item,info)和item_completed(self,results,item,info)这两个函数。

get_media_requests(self,item,info):通过该函数为image_urls中的每一个url生成一个Request。

for url in item['image_url']:  
    self.default_headers['referer']=url
    yield Request(url,headers=self.default_headers)

图片下载完毕后,处理结果会以二元组的方式返回给item_completed()函数。这个二元组定义为(success,image_info_or_failure)。其中,第一个元素表示图片是否下载成功,第二个元素是一个字典。

def item_completed(self, results, item, info):
    image_paths = [x['path'] for ok, x in results if ok]
    if not image_paths:
        raise DropItem("Item contains no images")
    item['image_paths'] = image_paths
    return item

下面以爬取尤果网上的美女图片为例,说明整个过程。

1、item.py,添加image_url与name字段,代码如下:

import scrapy

class UgirlsItem(scrapy.Item):
    # define the fields for your item here like:

    image_url=scrapy.Field()
    name=scrapy.Field()

2、在spider/ugirl.py 中写ImageSpider的代码

# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
from ..items import UgirlsItem

class UgirlSpider(scrapy.Spider):
    name = 'ugirl'
    allowed_domains = ['ugirls.com']
    start_urls = []
    for i in range(1,43):
        start_urls.append('https://www.ugirls.com/Content/Page-%d.html'%(i))

    def start_requests(self):
        for url in self.start_urls:
            yield Request(url=url,callback=self.parse)

    def parse(self, response):
        item=UgirlsItem()
        name=response.xpath('//div[@class="magazine_info"]/h2/a/text()').extract()
        image_url=response.xpath('//img[@class="magazine_img"]/@src').extract()
        item['name']=name
        item['image_url']=image_url
        yield item`

3、在pipelines.py中自定义ImagePipeline的代码

# -*- coding: utf-8 -*-

from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy.http import Request

class UgirlsPipeline(object):

    def process_item(self, item, spider):
        return item

class MyPipeline(ImagesPipeline):

    def get_media_requests(self,item,info):
        for image_url in item['image_url']:
            yield Request(image_url,meta={'item':item,'index':item['image_url'].index(image_url)})

    def item_completed(self,results,item,info):
        image_paths=[x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

4、最后在settings.py中进行下载路径等配置。

ITEM_PIPELINES={
'ugirls.pipelines.MyPipeline':200,
'ugirls.pipelines.UgirlsPipeline':300,
}

IMAGES_STORE= r'D:\programing\Python\Crawler\scrapy\ugirls\\'

IMAGE_EXPIRES=90

ITEM_PIPELINES中定义了各个管道的执行顺序,值的范围通常为0-1000,数值越小越先执行;IMAGES_STORE定义了爬取数据的存储位置;IMAGE_EXPIRES=90表示90天内不会下载重复的数据。

最后执行scrapy crawl ugirl命令,爬取结果如下图所示:

这里只是简单的应用了ImagePipeline爬取图片的方便功能,我们还可以创建缩略图和对图片进行分类。

猜你喜欢

转载自blog.csdn.net/dxk_093812/article/details/82315711