参考了这篇文章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