es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Ejecuta Scrapy desde un script cuando reciba una solicitud.

Tengo un servidor FastAPI que está escuchando en un endpoint, después de recibir cualquier solicitud post, usará Scrapy para recopilar algunos datos dependiendo de los datos que se obtengan de la solicitud post.

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings

class Request(BaseModel):
    someIDs: List[str]

process = CrawlerProcess(get_project_settings())

app = FastAPI()

@app.post("/")
def home(request: Request):
    process.crawl('rt_criteria', ids=request.someIDs)
    process.start()  # el script se bloqueará aquí hasta que se complete el crawling
    return {"crawled": True}

Este código se ejecutará la primera vez según lo esperado, pero la segunda vez, obtendré

twisted.internet.error.ReactorNotRestartable

error en:

process.start()

¿Dónde debo escribir esto y cómo puedo solucionar el error?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El error ReactorNotRestartable ocurre porque el Reactor de Twisted no puede reiniciarse después de haber sido detenido. Para solucionarlo, puedes mover la creación de la instancia CrawlerProcess y la función get_project_settings dentro de la función home, y utilizar la función reactor.run en lugar de process.start.

    Aquí está el código actualizado:

    from fastapi import FastAPI
    from pydantic import BaseModel
    from typing import List
    from scrapy.crawler import CrawlerRunner
    from scrapy.utils.project import get_project_settings
    from twisted.internet import reactor
    
    class Request(BaseModel):
        someIDs: List[str]
    
    app = FastAPI()
    
    @app.post("/")
    async def home(request: Request):
        process = CrawlerRunner()
        await process.crawl('rt_criteria', ids=request.someIDs)
        reactor.run()
    
        return {"crawled": True}
    
    # uvicorn main:app --reload
    

    En este código actualizado, la instancia CrawlerRunner se crea dentro de la función home, y se llama a la función reactor.stop() después de que se haya completado el rastreo. Además, la función process.start() se reemplaza por await process.crawl y se utiliza reactor.run para iniciar el Reactor de Twisted.

    Con estos cambios, el error ReactorNotRestartable no debería ocurrir.

Comments are closed.