scrapy —— ImagePipeline

 2023-09-06 阅读 23 评论 0

摘要:ImagePipeline Scrapy用ImagesPipeline类提供一种方便的方式来下载和存储图片。 主要特征 将下载图片转换成通用的JPG和RGB格式避免重复下载缩略图生成图片大小过滤 工作流程 爬取一个Item,将图片的URLs放入image_urls字段从Spider返回的Item,传递到Item Pipeli

ImagePipeline

Scrapy用ImagesPipeline类提供一种方便的方式来下载和存储图片。

主要特征

  • 将下载图片转换成通用的JPG和RGB格式
  • 避免重复下载
  • 缩略图生成
  • 图片大小过滤

工作流程

  • 爬取一个Item,将图片的URLs放入image_urls字段
  • Spider返回的Item,传递到Item Pipeline
  • Item传递到ImagePipeline,将调用Scrapy 调度器和下载器完成image_urls中的url的调度和下载。ImagePipeline会自动高优先级抓取这些url,于此同时,item会被锁定直到图片抓取完毕才被解锁。
  • 图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。

# 在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)
  • results实例
[(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

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/9875.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息