Для моего проекта Scrapy я использовал ImagesPipeline для загрузки изображений. Изображения хранятся с именами файлов, которые соответствуют хэшу SHA1 их URL-имен.
Мой вопрос: как я могу изменить имена, чтобы они содержали название другого поля, хранящегося в item['image_name']
Я смотрел на несколько предыдущих вопросов, в том числе,
Как изменить название загружаемого изображения в конвейерах? .
Scrapy image скачать как использовать пользовательское имя файла . Однако я не смог заставить ни один из этих методов работать. Особенно ответ 2017 года, так как это был самый близкий ответ на Scrapy 1.6, который я смог найти.
Из моего понимания, глядя на файл scrapy.pipelines.images.py, идея переименования файла проистекает из переопределения функции file_path, которая возвращает 'full/%s.jpg' % (image_guid)
Для этого я предполагаю, что конкретный контейнер элемента должен быть запрошен и сохранен в метаданных в функции get_media_request.
Я смущен, хотя мне неясно, как это происходит с полем изображения, которое, по-видимому, находится там, где происходит путь при беге паука.
Я не уверен в этом процессе, хотя и был бы очень признателен за помощь в этом вопросе.
Мой текущий код для Pipelines.py
class ImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
img_url = item['image_url']
meta = {'filename': item['image_name']}
yield Request(url=img_url, meta=meta)
def file_path(self, request, response=None, info=None):
image_guid = request.meta.get('filename', '')
return 'full/%s.jpg' % (image_guid)
Поле 'image_name' обновлено корректно, однако в поле 'images' 'path' по-прежнему является хешем SHA1 URL
------------------------------ Решение ------------- ---------------------
Решение этой проблемы было найдено. Основная проблема заключалась в том, что я не понимал, что для перезаписи конвейера мне нужно активно вызывать его в программу. Ниже приведен код, который устранил проблему.
pipelines.py
class CustomImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
return [Request(x, meta={'filename': item['image_name']}) for x in item.get(self.images_urls_field, [])]
def file_path(self, request, response=None, info=None):
image_guid = request.meta.get('filename', '')
return 'full/%s.jpg' % (image_guid)
settings.py
ITEM_PIPELINES = {'basicimage.pipelines.CustomImagesPipeline': 1,}
Где basicimage - мое личное имя проекта. После этого мне удалось немного адаптировать код, чтобы также можно было изменить имя папки каталога следующим образом.
class CustomImagesPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
meta = {'filename': item['image_name'], 'directoryname': item['directory']}
for x in item.get(self.images_urls_field, []):
return Request(x, meta=meta)
def file_path(self, request, response=None, info=None):
image_guid = request.meta.get('filename', '')
image_direct = request.meta.get('directoryname', '')
return '%s/%s.jpg' % (image_direct, image_guid)