在Scrapy中出现ReactorNotRestartable错误的原因是什么?
在Google Colab中使用Scrapy遇到ReactorNotRestartable错误的问题
我在Google Colab中使用Scrapy时,始终遇到ReactorNotRestartable错误:
我先通过pip install scrapy安装了Scrapy,随后使用以下代码:
import scrapy from scrapy.crawler import CrawlerProcess class TestSpider(scrapy.Spider): name="test" def start_requests(self): yield scrapy.Request("A valid URL") def parse(self, response): products=response.css("div.product-card") for item in products: yield { "price":products.css("div.price-range::text").get(), } process=CrawlerProcess(settings={ "FEED_URI" : "test.csv", "FEED_FORMAT" : "csv" }) process.crawl(TestSpider) process.start()
我是按照《如何在Python脚本中使用Scrapy》的教程操作的,但代码无法运行。请问我在使用Scrapy时为何会出现ReactorNotRestartable错误?
问题原因及解决办法
错误原因
ReactorNotRestartable错误的核心原因是:Scrapy依赖Twisted框架运行,而Twisted的反应器(Reactor)是单实例对象,启动后关闭就无法再次启动。在Google Colab这种交互式环境中,如果你多次运行同一个代码单元格,第一次运行已经启动并终止了反应器,第二次运行时再次调用process.start()就会触发这个错误;即使单次运行,也可能因环境残留的状态导致问题。
解决办法
这里提供几个实用的解决方式:
重启Colab运行时
点击Colab顶部菜单栏的「运行时」→「重启运行时」,之后重新运行代码单元格。这种方式能彻底重置环境,清除残留的反应器实例,是最简单直接的解决办法。修改代码避免重复启动反应器
在代码末尾加入sys.exit(),运行结束后主动退出进程,避免环境中残留状态。同时注意修复原代码中的小bug(遍历产品时应该用item而不是products取CSS选择器):
import scrapy from scrapy.crawler import CrawlerProcess import sys class TestSpider(scrapy.Spider): name="test" def start_requests(self): yield scrapy.Request("A valid URL") def parse(self, response): products=response.css("div.product-card") for item in products: yield { "price": item.css("div.price-range::text").get(), # 修正为item,确保每个产品取对应价格 } process=CrawlerProcess(settings={ "FEED_URI" : "test.csv", "FEED_FORMAT" : "csv" }) process.crawl(TestSpider) process.start() sys.exit() # 运行结束后退出,清理环境状态
- 改用CrawlerRunner控制反应器
CrawlerRunner不会自动启停反应器,你可以手动控制生命周期,更适配Colab这类交互式环境:
import scrapy from scrapy.crawler import CrawlerRunner from twisted.internet import reactor class TestSpider(scrapy.Spider): name="test" def start_requests(self): yield scrapy.Request("A valid URL") def parse(self, response): products=response.css("div.product-card") for item in products: yield { "price": item.css("div.price-range::text").get(), } runner = CrawlerRunner(settings={ "FEED_URI" : "test.csv", "FEED_FORMAT" : "csv" }) # 启动爬虫并在结束后停止反应器 d = runner.crawl(TestSpider) d.addBoth(lambda _: reactor.stop()) reactor.run()
内容的提问来源于stack exchange,提问作者daan
相关产品推荐
相关产品推荐

