【问题标题】:Scrapy file download how to use custom filenameScrapy文件下载如何使用自定义文件名
【发布时间】:2018-04-12 09:15:17
【问题描述】:

对于我的scrapy 项目,我目前使用的是FilesPipeline。下载的文件以 URL 的 SHA1 哈希值作为文件名存储。

[(True,
  {'checksum': '2b00042f7481c7b056c4b410d28f33cf',
   'path': 'full/0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg',
   'url': 'http://www.example.com/files/product1.pdf'}),
 (False,
  Failure(...))]

如何改用自定义文件名存储文件?

在上面的示例中,我希望文件名是 "product1_0a79c461a4062ac383dc4fade7bc09f1384a3910.pdf",因此我保持唯一性但使文件名可见。

作为起点,我探索了我的项目的pipelines.py,但没有取得多大成功。

import scrapy
from scrapy.pipelines.images import FilesPipeline
from scrapy.exceptions import DropItem

class MyFilesPipeline(FilesPipeline):

    def file_path(self, request, response=None, info=None):
        return request.meta.get('filename','')

    def get_media_requests(self, item, info):
        file_url = item['file_url']
        meta = {'filename': item['name']}
        yield Request(url=file_url, meta=meta)

在我的settings.py 中包含此参数

ITEM_PIPELINES = {
    #'scrapy.pipelines.files.FilesPipeline': 300
    'io_spider.pipelines.MyFilesPipeline': 200
}

已询问similar question,但它的目标是图像而不是文件。

任何帮助将不胜感激。

【问题讨论】:

    标签: python scrapy scrapy-spider scrapy-pipeline


    【解决方案1】:

    尝试使用file_path 方法:

    def file_path(self, request, response=None, info=None):
        url = request if not isinstance(request, Request) else request.url
        media_guid = hashlib.sha1(to_bytes(url)).hexdigest()
        path, media_ext = os.path.splitext(url)
        media_name = os.path.split(path)[1]
        return '%s_%s%s' % (media_name, media_guid, media_ext)
    

    (注意:这是未经测试的代码)

    【讨论】:

      【解决方案2】:

      file_path 应该返回文件的路径。在您的代码中,file_path 返回item['name'],这将是您的文件路径。注意默认file_pathcalculates SHA1 hashes。所以你的方法应该是这样的:

      def file_path(self, request, response=None, info=None):
          original_path = super(MyFilesPipeline, self).file_path(request, response=None, info=None)
          sha1_and_extension = original_path.split('/')[1] # delete 'full/' from the path
          return request.meta.get('filename','') + "_" + sha1_and_extension
      

      【讨论】:

      • 谢谢,这是我所期待的帮助 - 在我的上下文中,您的代码只是一个小问题,最后一个像将列表与字符串连接起来,所以我必须明确选择列表中的第一项return request.meta.get('filename','')[0] + "_" + sha1_and_extension
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多