Scrapy提供了一个 item pipeline ,来下载属于某个特定项目的图片,比如,当你抓取产品时,也想把它们的图片下载到本地。
这条管道,被称作图片管道,在 ImagesPipeline 类中实现,提供了一个方便并具有额外特性的方法,来下载并本地存储图片:
Pillow 是用来生成缩略图,并将图片归一化为JPEG/RGB格式,因此为了使用图片管道,你需要安装这个库。 Python Imaging Library (PIL) 在大多数情况下是有效的,但众所周知,在一些设置里会出现问题,因此我们推荐使用 Pillow 而不是 PIL.
- 首先在setting中激活以下
ITEM_PIPELINES = {
'chinazproject.pipelines.ChinazProjectImagePipeline': 299, # 激活图片下载管道
}
- pipelines
from scrapy.contrib.pipeline.images import ImagesPipeline
import scrapy
from chinazproject.items import ChinazprojectWebInfoItem,ChinazprojectTagItem
import os
# 取出配置文件
from scrapy.utils.project import get_project_settings
# os.remove()# 重命名
# 获取settings文件的信息
images_store = get_project_settings().get('IMAGES_STORE')
class ChinazProjectImagePipeline(ImagesPipeline):
def get_media_requests(self,item,info):
"""
根据图片的url地址,构造requuests请求
:param item:
:param info:
:return:
"""
if isinstance(item,ChinazprojectWebInfoItem):
# 获取图片地址,发起请求
img_url = 'http:'+item['coverImage']
print('获取图片地址', img_url)
yield scrapy.Request(img_url)
# 如果有多个图片地址,item['coverImage']对应的是一个列表
# img_urls = item['coverImage']
# return [scrapy.Request(x) for x in img_urls]
def item_completed(self,results,item,info):
"""
图片下载之后的回调结果
:param results: [(True/False,{'path':'图片下载之后的一个储存路径','url':'图片的url地址','ckecksum':'经过HASH加密的一个字符串'})]:图片下载成功还是失败
:param item:
:param info:
:return:
"""
if isinstance(item,ChinazprojectWebInfoItem):
paths = [result['path'] for status,result in results if status]
print('图片下载结果',results)
if len(paths)>0:
print('图片下载成功')
# 使用os的rename方法修改文件的名称
os.rename(images_store+'/'+paths[0],images_store+'/'+item['title']+'.jpg')
image_path = images_store+'/'+item['title']+'.jpg'
print('修改后的路径',image_path)
item['locakImgePath'] = image_path
else:
# 如果没有成功获取到图片,将这个item丢弃
from scrapy.exceptions import DropItem
raise DropItem('没有获取到图片,遗弃item')
# 获取图片地址,交给下一个管道处理
return item