Scrapy自定义启动脚本无法启动爬虫,执行后挂起无爬取行为
问题场景
我用scrapy crawl myspider命令可以正常启动爬虫,但用自定义脚本启动时,脚本仅打印添加蜘蛛的信息和启用插件的日志后就挂起,没有任何爬取行为,也看不到蜘蛛的后续日志,甚至没有相关网络流量。
我的自定义脚本几乎和Scrapy官方文档示例一致:
from scrapy.spiderloader import SpiderLoader from scrapy.crawler import CrawlerRunner from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging from twisted.internet import reactor settings = get_project_settings() configure_logging(settings) runner = CrawlerRunner(settings) spider_loader = SpiderLoader.from_settings(settings) for spider in spider_loader.list(): print(f"Adding Spider: {spider}") runner.crawl(spider_loader.load(spider)) d = runner.join() d.addBoth(lambda _: reactor.stop()) reactor.run()
脚本执行输出:
$ python3 minimal.py Adding Spider: myspider 2024-12-06 14:52:02 [scrapy.addons] INFO: Enabled addons: []
我确认蜘蛛本身是正常的(命令行可运行),实在找不到问题出在哪。
排查思路与解决方案
1. 核心原因:Reactor类型适配冲突
看你的项目settings.py里配置了TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor",这是基于asyncio的异步reactor。而你当前用CrawlerRunner手动调用reactor.run()的方式,和这个reactor类型存在异步循环适配问题,导致爬虫任务没有被正确调度执行。
解决办法:改用CrawlerProcess替代CrawlerRunnerCrawlerProcess是Scrapy提供的高层API,会自动处理reactor的初始化、运行和停止,无需手动管理reactor生命周期,能完美适配你配置的AsyncioSelectorReactor。修改后的脚本如下:
from scrapy.crawler import CrawlerProcess from scrapy.utils.project import get_project_settings from scrapy.utils.log import configure_logging from scrapy.spiderloader import SpiderLoader # 加载项目配置 settings = get_project_settings() # 配置日志系统 configure_logging(settings) # 初始化CrawlerProcess process = CrawlerProcess(settings) # 加载并启动所有蜘蛛 spider_loader = SpiderLoader.from_settings(settings) for spider_name in spider_loader.list(): print(f"Adding Spider: {spider_name}") spider_cls = spider_loader.load(spider_name) process.crawl(spider_cls) # 启动爬虫,自动处理reactor的启停 process.start()
2. 辅助排查:开启DEBUG日志定位隐藏问题
如果换用CrawlerProcess后仍有异常,可以先把日志级别调到DEBUG,查看更详细的初始化和调度日志,帮助定位隐藏问题(比如请求被拦截、蜘蛛初始化失败等)。在settings.py中添加:
LOG_LEVEL = "DEBUG"
3. 基础检查:确认脚本运行目录
确保运行minimal.py时,当前工作目录是Scrapy项目的根目录(即包含scrapy.cfg的目录)。如果不在根目录,get_project_settings()可能加载不到正确的配置,导致蜘蛛的start_urls、allowed_domains等规则失效,进而无爬取行为。
备注:内容来源于stack exchange,提问作者cast




