Scrapy 图片下载如何使用自定义文件名

14 投票
6 回答
14776 浏览
提问于 2025-04-16 18:43

在我的scrapy项目中,我现在使用的是ImagesPipeline。下载的图片会用它们的URL生成一个SHA1哈希值作为文件名来存储。

我该如何用我自己定义的文件名来存储这些文件呢?

如果我想要自定义的文件名中包含同一个项目的其他抓取字段呢?比如说,我想用item['desc']作为描述,并且用item['image_url']作为图片的文件名。如果我没理解错的话,这就需要在图片管道中以某种方式访问其他项目字段。

任何帮助都将不胜感激。

6 个回答

12

在 scrapy 0.12 版本中,我是这样解决这个问题的

class MyImagesPipeline(ImagesPipeline):

    #Name download version
    def image_key(self, url):
        image_guid = url.split('/')[-1]
        return 'full/%s.jpg' % (image_guid)

    #Name thumbnail version
    def thumb_key(self, url, thumb_id):
        image_guid = thumb_id + url.split('/')[-1]
        return 'thumbs/%s/%s.jpg' % (thumb_id, image_guid)

    def get_media_requests(self, item, info):
        yield Request(item['images'])
17

这只是对 scrapy 0.24 版本答案的更新(已编辑),其中的 image_key() 方法已经不再使用了。

class MyImagesPipeline(ImagesPipeline):

    #Name download version
    def file_path(self, request, response=None, info=None):
        #item=request.meta['item'] # Like this you can use all from item, not just url.
        image_guid = request.url.split('/')[-1]
        return 'full/%s' % (image_guid)

    #Name thumbnail version
    def thumb_path(self, request, thumb_id, response=None, info=None):
        image_guid = thumb_id + response.url.split('/')[-1]
        return 'thumbs/%s/%s.jpg' % (thumb_id, image_guid)

    def get_media_requests(self, item, info):
        #yield Request(item['images']) # Adding meta. I don't know, how to put it in one line :-)
        for image in item['images']:
            yield Request(image)
8

这是我在Scrapy 0.10中解决这个问题的方法。你可以查看FSImagesStoreChangeableDirectory中的persist_image方法。下载的图片文件名是关键。

class FSImagesStoreChangeableDirectory(FSImagesStore):

    def persist_image(self, key, image, buf, info,append_path):

        absolute_path = self._get_filesystem_path(append_path+'/'+key)
        self._mkdir(os.path.dirname(absolute_path), info)
        image.save(absolute_path)

class ProjectPipeline(ImagesPipeline):

    def __init__(self):
        super(ImagesPipeline, self).__init__()
        store_uri = settings.IMAGES_STORE
        if not store_uri:
            raise NotConfigured
        self.store = FSImagesStoreChangeableDirectory(store_uri)

撰写回答