Scrapy/Python: esperar a que una solicitud de yield termine antes de ejecutar el código (descarga de imágenes)
Tengo un proyecto cuyo propósito es extraer todos los capítulos de un libro (parsear), luego para cada capítulo, descargar las imágenes (parse_chapter) y crear un archivo PDF para el capítulo (create_pdf).
Aquí está mi código (ejemplo mínimo de trabajo):
def parse(self, response):
chapters = response.xpath('/html/body/div[1]/div/div[1]/div/div[4]/div/ul/li[1]/h5/a/@href')
for chapter in chapters:
yield scrapy.Request(chapter.get(), callback=self.parse_chapter)
def parse_chapter(self, response):
logging.debug("parse_chapter")
image_urls = response.xpath('/html/body/div[1]/div[3]/div/div[2]/div[2]/a/img/@src').get()
yield {
'image_urls' : image_urls
}
self.create_pdf()
# una vez que se crea el PDF => eliminar todas las imágenes
def create_pdf(self):
files = os.listdir(os.getcwd() + '/tmp/')
if len(files) > 0:
...
Además, ya modifiqué los archivos settings.py y pipelines.py.
El problema es: la función create_pdf se llama antes de que todas las imágenes se descarguen. ¿Hay alguna manera de esperar a que la solicitud de yield termine antes de ejecutar create_pdf?
davy.ai
Sí, se puede usar la palabra clave
yield
para pausar la ejecución deparse_chapter()
hasta que se descarguen todas las imágenes. Puede modificarparse_chapter()
de la siguiente manera:En
parse_chapter()
, iteramos sobre todas lasimage_urls
y creamos una solicitud para cada imagen usandoscrapy.Request()
. También emitimos un diccionario con una clave de'pdf_created'
y un valor deself.create_pdf()
. Esto pausará la ejecución hasta que se procesen todas las solicitudes de imagen y se devuelvan sus respuestas por Scrapy.En
create_pdf()
, verificamos la presencia de archivos de imagen en el directorio/tmp/
como antes. Sin embargo, ahora llamamos a esta función solo después de que se hayan descargado todas las imágenes.Tenga en cuenta que la respuesta de
parse_chapter()
contendrá tanto las URL de las imágenes como la clave'pdf_created'
. Deberá modificar su pipeline para manejar correctamente este diccionario.