scrapy的常用ImagesPipeline重写实现

参考了这篇文章https://www.xuebuyuan.com/140.html

在pipeline中重写重写一个pipeline并且继承ImagesPipeline
定义默认的item(若写成其他的字段则需要在get_media_requests里重写)
class ImageItem(scrapy.Item):
    image_urls = scrapy.Field()
    images = scrapy.Field()
重写ImagesPipeline
import hashlib  # 下载图片地址哈希命名
from scrapy.http import Request  # 请求下载图片管道用
from scrapy.pipelines.images import ImagesPipeline
from scrapy.utils.python import to_bytes  # 下载图片用
from .items import WebSiteNewsItem

class DownloadImagesPipeline(ImagesPipeline):  # 下载图片的管道,

    def get_media_requests(self, item, info):  # 请求获取图片
        '''ImagePipeline根据image_urls中指定的url进行爬取,若不用默认字段则在这里重写
           可以通过get_media_requests为每个url生成一个Request
           get_media_requests函数返回示例如下:
           [(True,
               {’checksum’: ’2b00042f7481c7b056c4b410d28f33cf’,
               ’path’: ’full/7d97e98f8af710c7e7fe703abc8f639e0ee507c4.jpg’,
               ’url’: ’http://www.example.com/images/product1.jpg’}),
           (True,
               {’checksum’: ’b9628c4ab9b595f72f280b90c4fd093d’,
               ’path’: ’full/1ca5879492b8fd606df1964ea3c1e2f4520f076f.jpg’,
               ’url’: ’http://www.example.com/images/product2.jpg’}),
           (False,
               Failure(...))]
        '''
        if isinstance(item, WebSiteNewsItem) and item.get('image_list') and item.get('publish_date'):
            for image_url in item['image_list'].split(u','):  # 从item的image_list字段中 分割出图片链接地址
                yield Request(image_url.replace('\\', '/'), meta={'publish_date': info.spider.publish_date},
                              headers={'Referer': item['url']})
                # 链接中"\\"替换为"/" 向图片地址发出请求

    def item_completed(self, results, item, info):
        '''所有图片处理完毕后(不管下载成功或失败),会调用item_completed进行处理
           results是一个list 第一个为图片下载状态,
           get_media_requests在图片下载完毕后,处理结果会以二元组的方式返回给item_completed()函数的
           results,图片下载状态定义如下:
               (success, image_info_or_failure)  
               success表示图片是否下载成功;image_info_or_failure是一个字典
        '''
        image_paths = [info.get('path', None) for success, info in results if success and info]
        if not image_paths:
            return item
        if isinstance(item, WebSiteNewsItem):
            item['image_list'] = u','.join(image_paths)
        return item

    def file_path(self, request, response=None, info=None):
        image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()  # 对请求地址取哈希值
        return u'%s/%s/%s.jpg' % (

            request.meta['publish_date'].strftime('%Y-%m/%Y%m%d'),  # 这里构建了两级地址
            info.spider.zh_name, image_guid)
        # 发表日期,爬虫中文名,哈希值拼成路径,存储图片的路径类似于:2018-10/20181017/爬虫中文名/图片哈希值
配置好settings
import os

import os
ITEM_PIPELINES = {
    #自定义的pipelines
    'articleSpider.pipelines.MyImagesPipeline': 300,
}
#自定义存储imageurl的字段,item["front_image_url"]
IMAGES_URL_FILED = "front_image_url"
#工程根目录
project_dir = os.path.dirname(__file__)
#下载图片存储位置
IMAGES_STORE = os.path.join(project_dir, 'images')

# 其他参数
# 该字段的值为XxxItem中定义的存储图片链接的image_urls字段
# IMAGES_URLS_FIELD='image_urls'
# 该字段的值为XxxItem中定义的存储图片信息的images字段
# IMAGES_RESULT_FIELD='images'
# 生成缩略图(可选)
'''
IMAGES_THUMBS = {
    'small': (50, 50),
    'big': (270, 270),
}
'''
# 过期时间,单位:天(可选)
# IMAGES_EXPIRES = 120
# 过滤小图片(可选)
# IMAGES_MIN_HEIGHT = 110
# IMAGES_MIN_WIDTH = 110
# 是否允许重定向(可选)
# MEDIA_ALLOW_REDIRECTS = True
    原文作者:刹那的既视感
    原文地址: https://www.jianshu.com/p/cd05763d49e8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞