MENU

scrapy值图片下载管道以及保存本地

前言

对于图片下载,在scrapy框架中提供了专门下载的Pipeline,即ImagesPipeline这个是定义好的。但是对于我们来说,他的局限性很大,所以基本上我们需要重写一个Pipeline。怎么局限性?
内置的ImagesPipeline会默认读取Item的image_urls字段,并认为该字段是一个列表形式,它会遍历Item的image_urls字段,然后取出每个URL进行图片下载。而我们业务逻辑往往不是这样。

实现

  • setting.py设置图片保存路径

    # 图片存储
    IMAGES_STORE = './images'
    
  • 自定义Pipeline并且重写ImagesPipeline方法

    from scrapy.exceptions import DropItem
    from scrapy.pipelines.images import ImagesPipeline
    
    class ImagePipeline(ImagesPipeline):
    
      def file_path(self, request, response=None, info=None):
          item = request.meta['item']
          url = request.url
          file_name = item['imagename'] + '/' + url.split('/')[-1]  # imagename为博主定义的 这个可以更改为你在item传入值
          return file_name
    
      def get_media_requests(self, item, info):
          if item['img']:  # 这里假定img为需要下载的图片链接 实际按需更改
              yield scrapy.Request(item['img'], meta={'item': item})
          else:
              return item
    
      def item_completed(self, results, item, info):
          image_path = [x['path'] for ok, x in results if ok]
          if not image_path:
              raise DropItem("Item contains no images")
          item['img'] = image_path 
          return item
    
  • setting.py文件引入ImagePipeline管道

    # 引入ImagePipeline管道
     ITEM_PIPELINES = {
         'xxxxx.pipelines.ImagePipeline': 300,  # 300表示优先级,按照自己实际逻辑先后执行顺序
     }
    

说明

  • get_media_requests() 它的第一个参数item是爬取生成的Item对象。我们将它的url字段取出来,然后直接生成Request对象。此Request加入到调度队列,等待被调度,执行下载。
  • file_path() 它的第一个参数request就是当前下载对应的Request对象。这个方法用来返回保存的文件名,直接将图片链接的最后一部分当作文件名即可。它利用split()函数分割链接并提取最后一部分,返回结果。这样此图片下载之后保存的名称就是该函数返回的文件名。
  • item_completed() 它是当单个Item完成下载时的处理方法。因为并不是每张图片都会下载成功,所以我们需要分析下载结果并剔除下载失败的图片。如果某张图片下载失败,那么我们就不需保存此Item到数据库。该方法的第一个参数results就是该Item对应的下载结果,它是一个列表形式,列表每一个元素是一个元组,其中包含了下载成功或失败的信息。这里我们遍历下载结果找出所有成功的下载列表。如果列表为空,那么该Item对应的图片下载失败,随即抛出异常DropItem,该Item忽略。否则返回该Item,说明此Item有效。

项目实战

Python基于Scrapy爬取www.rkpass.cn题目

本文参考:Scrapy框架的使用之Item Pipeline的用法

标签: Python, Scrapy
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码