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

时间:2011-05-31 21:57:05

标签: python scrapy

对于我scrapy项目,我目前正在使用ImagesPipeline。下载的图像是其网址的stored with a SHA1 hash作为文件名。

如何使用我自己的自定义文件名来存储文件?

如果我的自定义文件名需要包含同一项中的另一个已删除字段,该怎么办?例如使用item['desc']item['image_url']图片的文件名。如果我理解正确,那将涉及以某种方式访问​​图像管道中的其他项目字段。

任何帮助将不胜感激。

6 个答案:

答案 0 :(得分:16)

这只是scrapy 0.24(EDITED)答案的实现,其中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. Dunno how to put it in one line :-)
        for image in item['images']:
            yield Request(image)

答案 1 :(得分: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'])

答案 2 :(得分: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)

答案 3 :(得分:6)

我在2017年找到了自己的方式,scrapy 1.1.3

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

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

与上面的代码一样,您可以在get_media_requests()中将您想要的名称添加到“请求”元组中,然后通过file_path()将其重新载入request.meta.get('yourname','')

答案 4 :(得分:2)

我做了一个讨厌的快速黑客。就我而言,我将图像标题存储在我的Feed中。而且,每个项目只有1 image_urls,因此,我编写了以下脚本。它基本上将/images/full/目录中的图像文件重命名为我作为json存储的项目Feed中的相应标题。

import os
import json

img_dir = os.path.join(os.getcwd(), 'images\\full')
item_dir = os.path.join(os.getcwd(), 'data.json')

with open(item_dir, 'r') as item_json:
    items = json.load(item_json)

for item in items:
    if len(item['images']) > 0:
        cur_file = item['images'][0]['path'].split('/')[-1]
        cur_format = cur_file.split('.')[-1]
        new_title = item['title']+'.%s'%cur_format
        file_path = os.path.join(img_dir, cur_file)
        os.rename(file_path, os.path.join(img_dir, new_title))

这是讨厌的&不建议。但是,这是一种天真的替代方法。

答案 5 :(得分:0)

我重写了代码,改变了,在thumb_path def中,"响应。"通过"请求。"。如果不是,它就不会起作用,因为"响应设置为无"。

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 + request.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. Dunno how to put it in one line :-)
        for image in item['images']:
            yield Request(image)