ImagesPipeline是scrapy自带的类,用来处理图片(爬取时将图片下载到本地)用的。

优势:

    1. 将下载图片转换成通用的JPG和RGB格式
    2. 避免重复下载
    3. 缩略图生成
    4. 图片大小过滤
    5. 异步下载
    6. ......

工作流程:

    1. 爬取一个Item,将图片的URLs放入image_urls字段
    2. Spider返回的Item,传递到Item Pipeline
    3. Item传递到ImagePipeline,将调用Scrapy 调度器和下载器完成image_urls中的url的调度和下载。
    4. 图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。

实现方式:

    1. 自定义pipeline,优势在于可以重写ImagePipeline类中的实现方法,可以根据情况对照片进行分类;
    2. 直接使用ImagePipeline类,简单但不够灵活;所有的图片都是保存在full文件夹下,不能进行分类

  项目实现:

  需求:爬取彼岸图库的图片,并保存在本地文件夹,url:http://pic.netbian.com/

  spider爬虫文件(数据解析),获取图片url。biantu.py

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


class BiantuSpider(scrapy.Spider):
    name = 'biantu'
    # allowed_domains = ['www.xx.com']
    start_urls = ['http://pic.netbian.com/']

    # 数据解析
    def parse(self, response):
        li_list = response.xpath('//*[@>)
        for li in li_list:
            img_url = "http://pic.netbian.com/"+li.xpath('./a/span/img/@src').extract_first()

            # 实例化一个item对象
            item = BiantuproItem()
            item["img_url"] = img_url

            # 提交对象到管道
            yield item

  配置图片存储的item对象类。items.py

import scrapy


class BiantuproItem(scrapy.Item):
    # define the fields for your item here like:
    # 存储图片地址
    img_url = scrapy.Field()

  配置管道类,这里我们下载图片是自定义一个图片下载类,并继承scrapy中专门处理图片下载的类(ImagesPipeline)。pipelines.py

from scrapy.pipelines.images import ImagesPipeline
import scrapy


# 自定义 创建下载及存储的特殊管道类
class MyImagePipeline(ImagesPipeline):
    # 接收item对象并将获取item对象中的url发送请求
    def get_media_requests(self, item, info):
        yield scrapy.Request(item["img_url"])

    # 指定文件存储路径
    def file_path(self, request, response=None, info=None):
        # 打印图片路径
        # print(request.url)
        # 通过分割图片路径获取图片名字
        img_name = request.url.split("/")[-1]
        return img_name

    # 返回item对象,给下一执行的管道类
    def item_completed(self, results, item, info):
        # 图片下载路径、url和校验和等信息
        print(results)
        return item

  scrapy配置文件,配置图片存放位置及开启管道。settings.py

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

LOG_LEVEL = "ERROR"

# 指定文件保存位置
IMAGES_STORE = "imgsLab"

# 配置管道
ITEM_PIPELINES = {
   'biantuPro.pipelines.MyImagePipeline': 300,
}