Scrapy_ImagePipeline保存图片
Scrapy提供了一个 ImagePipeline,用来下载图片这条管道,图片管道ImagesPipeline
提供了方便并具有额外特性的功能,比如:
- 将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
- 避免重新下载最近已经下载过的图片
- 缩略图生成
- 检测图像的宽/高,确保它们满足最小限制
1 使用图片管道
scrapy.pipelines.images.ImagesPipeline
使用 ImagesPipeline ,典型的工作流程如下所示:
- 在一个爬虫中,把图片的URL放入
image_urls
组内(image_urls是个列表) - URL从爬虫内返回,进入图片管道
- 当图片对象进入 ImagesPipeline,image_urls 组内的URLs将被Scrapy的调度器和下载器安排下载
- settings.py文件中配置保存图片路径参数
IMAGES_STORE
- 开启管道
注意
需要安装pillow4.0.0以上版本
pip install pillow==9.2.0
问题
报错:twisted.python.failure.Failure OpenSSL.SSL.Error
解决方案
pip uninstall cryptography pip install cryptography==36.0.2
Scrapy_自定义ImagePipeline
问题
使用官方默认图片管道,有如下几个问题:
- 文件名不友好
- 存储图片URL的参数名称与类型太固定
解决方案
自定义ImagePipeline,扩展
1 自定义图片管道
-
继承
scrapy.pipelines.images import ImagesPipeline
-
实现
get_media_requests(self, item, info)
方法- 发送请求,下载图片
- 转发文件名
-
实现
file_path(self,request,response=None,info=None,*,item=None)
- 修改文件名与保存路径
2 代码
import re
class Scrapy05Pipeline:
def process_item(self, item, spider):
return item
from scrapy.pipelines.images import ImagesPipeline
from scrapy.http.request import Request
class MyImagePipeline(ImagesPipeline):
def get_media_requests(self, item, info):
return Request(item['image_url'])
def file_path(self, request, response=None, info=None, *, item=None):
# 处理文件名中的特殊字符
# name = item.get('name').strip().replace('\r\n\t\t','').replace('(','').replace(')','').replace('/','_')
name = re.sub('/','_',re.sub('[\s()]','',item.get('name')))
return f'{name}.jpg'