Как загрузить скрап-изображения в динамическую папку?

Я могу загружать изображения с помощью scrapy в папку "Full", но мне нужно сделать имя папки назначения динамическим, например full/session_idКаждый раз, когда проходит скрапа.

Есть какой-либо способ сделать это?

1 ответ

Решение

Я не работал с ImagesPipeline пока, но следуя документации, я бы переопределил item_completed(results, items, info),

Исходное определение:

def item_completed(self, results, item, info):
    if self.IMAGES_RESULT_FIELD in item.fields:
        item[self.IMAGES_RESULT_FIELD] = [x for ok, x in results if ok]
    return item

Это должно дать вам наборы результатов загруженных изображений, включая путь (кажется, что на один элемент может быть много изображений).

Если вы теперь измените этот метод в подклассе, чтобы переместить все файлы перед установкой пути, он должен работать так, как вы хотите. Вы можете установить целевую папку для вашего элемента в нечто вроде item['session_path'], Вы должны будете установить этот параметр для каждого предмета, прежде чем возвращать / отдавать свои предметы от паука.

Подкласс с переопределенным методом может выглядеть так:

import os, os.path
from scrapy.contrib.pipeline.images import ImagesPipeline

class SessionImagesPipeline(ImagesPipeline):
    def item_completed(self, results, item, info):
        # iterate over the local file paths of all downloaded images
        for result in [x for ok, x in results if ok]:
            path = result['path']
            # here we create the session-path where the files should be in the end
            # you'll have to change this path creation depending on your needs
            target_path = os.path.join((item['session_path'], os.basename(path)))

            # try to move the file and raise exception if not possible
            if not os.rename(path, target_path):
                raise ImageException("Could not move image to target folder")

            # here we'll write out the result with the new path,
            # if there is a result field on the item (just like the original code does)
            if self.IMAGES_RESULT_FIELD in item.fields:
                result['path'] = target_path
                item[self.IMAGES_RESULT_FIELD].append(result)

        return item

Еще лучше было бы установить желаемый путь сеанса не в item, но в настройках во время твоего скрапа беги. Для этого вам нужно выяснить, как настроить config во время работы приложения, и вам придется переопределить конструктор, я думаю.

Вот ответ stackru.com

class StoreImgPipeline(ImagesPipeline):
    def file_path(self, request, response=None, info=None):
        image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()
        return 'realty-sc/%s/%s/%s/%s.jpg' % (YEAR, image_guid[:2], image_guid[2:4], image_guid)
Другие вопросы по тегам