我已经部署了一个Scrapy项目,每当lambda api请求到来时,它就会爬网。
它在第一次API调用时运行良好,但后来失败并抛出ReactorNotRestartable错误。
据我所知,AWS Lambda生态系统没有杀死进程,因此reactor仍然存在于内存中。
lambda日志错误如下:
Traceback (most recent call last):
File "/var/task/aws-lambda.py", line 42, in run_company_details_scrapy
process.start()
File "./lib/scrapy/crawler.py", line 280, in start
reactor.run(installSignalHandlers=False) # blocking call
File "./lib/twisted/internet/base.py", line 1242, in run
self.startRunning(installSignalHandlers=installSignalHandlers)
File "./lib/twisted/internet/base.py", line 1222, in startRunning
ReactorBase.startRunning(self)
File "./lib/twisted/internet/base.py", line 730, in startRunning
raise error.ReactorNotRestartable()
ReactorNotRestartable
lambda处理函数为:
def run_company_details_scrapy(event, context):
process = CrawlerProcess()
process.crawl(CompanyDetailsSpidySpider)
process.start()
我有一个变通办法,通过在start函数中插入一个标志,不停止reactor
process.start(stop_after_crawl=False)
但这样做的问题是,我必须等到lambda调用超时。
尝试了其他的解决方案,但似乎都不起作用。有人能指导我如何解决这个问题吗?
4条答案
按热度按时间pgky5nke1#
最近也有同样的问题,钩针不想工作的各种原因。
最后,我们采用了肮脏的解决方案:只需在lambda处理函数的末尾调用
sys.exit(0)
(或者sys.exit(1)
,如果捕捉到错误,并不意味着返回代码AFAICT)。如果您打算从Lambda返回一个 response,这显然不太好,但是如果您使用Scrapy,数据可能已经通过您的管道持久化了,使用调度程序作为Lambda的触发器,因此不需要响应。
注意:您 * 将 * 在CloudWatch中收到AWS的通知:
hlswsv352#
这个问题并不是AWS Lambda独有的-请参阅running a spider in a Celery task。
您可以尝试ScrapyScript(披露:它生成一个子进程来支持Twisted reactor,阻塞直到所有提供的spider都完成,然后退出。它是考虑到Celery而编写的,但是用例是相似的。
在您的情况下,这应该是可行的:
r7xajy2e3#
我在AWS lambda上遇到了错误
ReactorNotRestartable
,在我找到这个解决方案之后默认情况下,
scrapy
的异步特性不会很好地与云函数一起工作,因为我们需要一种方法来阻止爬行,以防止函数提前返回,并防止在进程终止前杀死示例。相反,我们可以使用
scrapydo
以阻塞方式运行现有的spider:e1xvtsh34#
您可以尝试使用https://pypi.python.org/pypi/crochet来协调在Lambda控制的主线程的非主线程中运行的React器的使用。
Crochet将为您完成线程化React器的初始化,并提供工具,使您可以轻松地从main调用React器线程中的代码(并获得结果)。
这可能更符合Lambda对您的代码的期望。