You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时运行带有不同CrawlerRunner配置的Scrapy爬虫?

正确实现方式

问题根源

你的代码无法运行的核心问题有两个:

  • 为每个爬虫的crawl()结果都绑定了reactor.stop(),导致第一个爬虫执行完毕就立刻终止Twisted reactor,后续爬虫根本没有启动的机会。
  • 完全不需要创建多个CrawlerRunner实例,单个CrawlerRunner就可以同时管理多个带有不同配置的爬虫。

方案一:单个CrawlerRunner + 爬虫独立配置(推荐)

利用CrawlerRunner.crawl()方法的settings参数,为每个爬虫单独指定FEEDS配置,覆盖全局设置。这样既简洁又能保证所有爬虫并行执行,直到全部完成再停止reactor。

示例代码:

import scrapy
from twisted.internet import reactor
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging
from scrapy.utils.project import get_project_settings

# 假设你的爬虫定义如下
class Live1(scrapy.Spider):
    name = "live1"
    # 你的爬虫逻辑...

class Live2(scrapy.Spider):
    name = "live2"
    # 你的爬虫逻辑...

class Live3(scrapy.Spider):
    name = "live3"
    # 你的爬虫逻辑...

configure_logging()
# 获取项目全局设置,也可以直接用空字典自定义基础设置
base_settings = get_project_settings()
runner = CrawlerRunner(base_settings)

# 为每个爬虫单独传入FEEDS配置
runner.crawl(Live1, settings={
    "FEEDS": {
        r"C:\Users\Messi\1.json": {"format": "json", "overwrite": True}
    }
})
runner.crawl(Live2, settings={
    "FEEDS": {
        r"C:\Users\Messi\2.json": {"format": "json", "overwrite": True}
    }
})
runner.crawl(Live3, settings={
    "FEEDS": {
        r"C:\Users\Messi\3.json": {"format": "json", "overwrite": True}
    }
})

# 等待所有爬虫完成后再停止reactor
d = runner.join()
d.addBoth(lambda _: reactor.stop())

reactor.run()

注意点:

  • FEEDS路径可以不用file://协议,直接用本地绝对路径更简洁(Windows下注意转义,或者用原始字符串r"")。
  • get_project_settings()会加载项目的settings.py配置,如果不需要全局配置,也可以直接传入{}作为基础设置。

方案二:多个CrawlerRunner(不推荐)

如果一定要使用多个CrawlerRunner实例,需要将所有爬虫的Deferred对象合并,统一在全部完成后再停止reactor,而不是每个单独绑定stop操作。

示例代码:

import scrapy
from twisted.internet import reactor, defer
from scrapy.crawler import CrawlerRunner
from scrapy.utils.log import configure_logging

class Live1(scrapy.Spider):
    name = "live1"
    # 爬虫逻辑...

class Live2(scrapy.Spider):
    name = "live2"
    # 爬虫逻辑...

class Live3(scrapy.Spider):
    name = "live3"
    # 爬虫逻辑...

configure_logging()

runner1 = CrawlerRunner(settings={
    "FEEDS": {r"C:\Users\Messi\1.json": {"format": "json", "overwrite": True}}
})
runner2 = CrawlerRunner(settings={
    "FEEDS": {r"C:\Users\Messi\2.json": {"format": "json", "overwrite": True}}
})
runner3 = CrawlerRunner(settings={
    "FEEDS": {r"C:\Users\Messi\3.json": {"format": "json", "overwrite": True}}
})

# 收集所有爬虫的Deferred对象
deferreds = [
    runner1.crawl(Live1),
    runner2.crawl(Live2),
    runner3.crawl(Live3)
]

# 合并所有Deferred,全部完成后停止reactor
d = defer.gatherResults(deferreds)
d.addBoth(lambda _: reactor.stop())

reactor.run()

为什么不推荐这个方案?

多个CrawlerRunner会初始化多个独立的配置环境,增加不必要的资源开销,而且单个CrawlerRunner完全能满足需求,代码更简洁易维护。

内容的提问来源于stack exchange,提问作者user19925544

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 19:20:58