Scrapy用ImagesPipeline
类提供一种方便的方式来下载和存储图片。
image_urls
字段Spider
返回的Item,传递到Item Pipeline
Item
传递到ImagePipeline
,将调用Scrapy 调度器和下载器完成image_urls
中的url的调度和下载。ImagePipeline会自动高优先级抓取这些url,于此同时,item会被锁定直到图片抓取完毕才被解锁。
# 在settings中的配置信息(IMAGES_STORE 是必须的,其他可选)IMAGES_STORE = 'D:\\dev\\python\\scrapy\\demo\\img' # 图片存储路径
IMAGES_EXPIRES = 90 # 过期天数
IMAGES_MIN_HEIGHT = 100 # 图片的最小高度
IMAGES_MIN_WIDTH = 100 # 图片的最小宽度
# 图片的尺寸小于IMAGES_MIN_WIDTH*IMAGES_MIN_HEIGHT的图片都会被过滤
需要在自定义的ImagePipeline类中重载的方法:
def get_media_requests(self, item, info):# 取出item中的图片链接生成请求对象,必须重写return [Request(x) for x in item.get(self.images_urls_field, [])]def item_completed(self, results, item, info):# 判断item是否是个字典,请求是否成功if isinstance(item, dict) or self.images_result_field in item.fields:"""results 是一个元组列表:[(下载是否成功布尔型,{'url':"图片链接",'path':'图片当前存储路径和名称', 'chechsum':'md5编码'})]"""item[self.images_result_field] = [x for ok, x in results if ok]# 列表推导式,判断下载是否成功,如果是取出字典部分返回return itemdef file_path(self, request, response=None, info=None):# 对图片的原始名称进行sha1加密,确保唯一性,生成新的图片名称image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()return 'full/%s.jpg' % (image_guid)
[(True, {'url': 'https://rpic.douyucdn.cn/live-cover/appCovers/2018/11/02/5360862_20181102112804_big.jpg','path': 'full/2fffd06f549900fce978106feb62889f3a0d96e7.jpg', 'checksum': '2f1c8e6c2e0eca5872cc93f0608addfd'})]
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.http import Request
from scrapy.exceptions import DropItemclass MyImagesPipeline(ImagesPipeline):def get_media_requests(self, item, info):# 从item中取出image的url,生成请求对象for image_url in item['image_urls']: yield Request(image_url)"""对图片重命名的两种方式:一重写file_path方法,直接干涉图片名的生成""" # 对url进行切割,取出url的最后一部分作为文件名,但是有时候imge_url的末尾并不是xxx.png等图片的名称,需要自己判断一下 def file_path(self, request, response=None, info=None):# 从request中取出url,切割取最后一部分image_guid = request.url.split('/')[-1] return 'full/%s' % (image_guid) # 返回图片名# 该方法可写可不写,判断图片是否下载完成def item_completed(self, results, item, info):# 不知道results是什么的看上面源码解析image_paths = [x['path'] for ok, x in results if ok]if not image_paths:raise DropItem("Item contains no images")return item
rom scrapy.pipelines.images import ImagesPipelinefrom scrapy.http import Request
from .settings import IMAGES_STORE
import os# 使用scrapy 下载图片 imagesPipeline
class DouyuImagePipeline(ImagesPipeline):def get_media_requests(self, item, info):# 1.图片url item['']image_url = item['vertical_src']# 2.发图片请求--engine--sheduler--engine-yield Request(image_url)"""对图片重命名的两种方式:二在函数item_completed中将已经生成的图片名称替换成item中的某个字段"""# 图片下载完毕def item_completed(self, results, item, info):# 更换 图片的名字 昵称# 1. 老的 图片路径old_path = IMAGES_STORE + [x['path'] for ok, x in results if ok][0]# 2. 新的 图片路径new_path = IMAGES_STORE + item['nickname'] + '.jpg'# 3. os替换rename() 重点,使用rename()函数替换名称# 循环之后 因为 没有上传头像的用户--占位图 地址一样 倒置, 后面的 用户的 无法替换try:os.rename(old_path, new_path)except Exception as e:print('默认图片已经替换完毕!')return item
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态