scrapy采集的图片如何保存在不同的文件夹?

新手上路,请多包涵

有时候爬虫爬到不同内容的图片,例如头像一类,动态内容的图片又是一类,如何能在scrapy下载的时候分开文件夹存储?
找到修改图片名存储的方法,参考:https://segmentfault.com/q/10...
但是这个方法只能修改图片名去存储,没法改变路径。

clipboard.png
即使我在file_path方法中强制多加一个/a/的路径,也不行。这样,根本就没图像下载,打开Pic文件夹,空空如也。

clipboard.png

请问如何修改图片保存的路径呢?

阅读 10.2k
3 个回答

不用在process_item里写,这个函数还是用来干过滤比较合适。
你重写file_path的做法没错,因为file_path只返回一个字符串,后续的处理还在ImagesPipeline类的其他函数里。同时要配合get_media_requests传递meta,不然拿不到item的,请参考:

def get_media_requests(self, item, info):
    for image_url in item['image_urls']:
        yield scrapy.Request(url=image_url, headers={'Referer': item['page_url'][0]}, meta={'item': item})

def file_path(self, request, response=None, info=None):
    item = request.meta['item']
    path = "covers/%s.%s" % (item['id'][0],
                            item['image_urls'][0].split('.')[-1])
    return path

我猜你出问题的地方还有setting.py里没写对自定义的类名,这样的话scrapy还是在用默认的pipeline在跑,你再怎么改也一样,注意一下下面这两个地方吧,都要设定的。

ITEM_PIPELINES = {'yourproject.pipelines.**MyImagesPipeline**': 100}
IMAGES_STORE = '/yourpath'

setting中修改配置了吗,这是我自己写的一个方法,你可以参考下
image_urls是图片的地址,
img_postfix是图片的后缀,默认是jpg,
name是图片的名字
filepath是图片的存储路径
header就是他的请求的的header,有的可能需要

class ImagesPipeline(object):
    def process_item(self, item, spider):
        headers = None
        if 'image_urls' in item:  # 如何‘图片地址’在项目中
            dir_path = '%s' % (item['filepath'])
            if not os.path.exists(dir_path):
                os.makedirs(dir_path)
            if 'img_postfix' in item:
                file_path = '%s/%s.%s' % (dir_path, item['name'], item['img_postfix'])
            else:
                file_path = '%s/%s.jpg' % (dir_path, item['name'])
            if os.path.exists(file_path):
                del item
                return None
            else:
                images = file_path
                if 'header' in item:
                    headers = item['header'][0]
                with open(file_path, 'wb') as handle:
                    response = requests.get(item['image_urls'], stream=True,headers=headers)
                    for block in response.iter_content(1024):
                        if not block:
                            break
                        handle.write(block)
                item['images'] = images
                return item
新手上路,请多包涵
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏