Как загрузить скрап-изображения в динамическую папку?
Я могу загружать изображения с помощью 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)