Scrapy 如何在同一进程内并行或顺序运行多个 spider?AsyncCrawlerProcess 与 AsyncCrawlerRunner 用法

发布时间:2026/9/15 16:18:43
Scrapy 如何在同一进程内并行或顺序运行多个 spider?AsyncCrawlerProcess 与 AsyncCrawlerRunner 用法 Scrapy 如何在同一进程内并行或顺序运行多个 spiderAsyncCrawlerProcess 与 AsyncCrawlerRunner 用法【免费下载链接】scrapyScrapy, a fast high-level web crawling scraping framework for Python.项目地址: https://gitcode.com/GitHub_Trending/sc/scrapy默认情况下scrapy crawl每次只在一个进程中运行一个 spider。Scrapy 的内部 API 支持在同一个进程内运行多个 spider每次调用crawl()都会创建一个独立的Crawler对象拥有各自的 downloader、spider middleware 和已解析的设置包括 spider 级设置不同 spider 之间互不共享。完成这个任务有两个入口类AsyncCrawlerProcess和AsyncCrawlerRunner两者都提供基于协程的 API对应的 Deferred 风格旧版是CrawlerProcess/CrawlerRunner。两个入口类的适用条件选择哪个类取决于你的脚本是否已经有事件循环AsyncCrawlerProcess会自己启动 Twisted reactor 或 asyncio 事件循环并配置日志、安装 Ctrl-C 等关闭信号处理器。当你没有在应用中运行其他 reactor 时用它。它的start()是阻塞调用直到爬取结束才返回。AsyncCrawlerRunner只是对多个 crawler 的薄封装不会启动或干扰已有的 reactor。当你的应用已经使用 Twisted、希望在同一个 reactor 内运行 Scrapy 时应选它。注意两点前提当TWISTED_REACTOR_ENABLED为True默认时要求已安装twisted.internet.asyncioreactor.AsyncioSelectorReactor当设置为False时要求进程中没有安装 Twisted reactor但已安装 asyncio 事件循环。在 Scrapy 项目内运行时还可以把 spider 名字符串传给crawl()由 spider loader 自动加载项目设置可用scrapy.utils.project.get_project_settings获取作为AsyncCrawlerProcess构造参数传入。用 AsyncCrawlerProcess 并行运行多个 spiderAsyncCrawlerProcess下并行最简单连续调用多次crawl()后再start()脚本会阻塞直到所有爬取任务结束。以下示例来自官方文档其中MySpider1/MySpider2需替换为你自己的 spider 类import scrapy from scrapy.crawler import AsyncCrawlerProcess from scrapy.utils.project import get_project_settings class MySpider1(scrapy.Spider): # 第一个 spider 的定义 ... class MySpider2(scrapy.Spider): # 第二个 spider 的定义 ... settings get_project_settings() process AsyncCrawlerProcess(settings) process.crawl(MySpider1) process.crawl(MySpider2) process.start() # 阻塞直到所有爬取任务结束判断完成的依据start()文档说明其为阻塞调用当stop_after_crawlTrue默认时所有 crawler 结束后 reactor/事件循环会停止并返回。如果你需要程序化地等待crawl()返回的asyncio.Task在该 spider 爬取完成时结束也可以调用join()所有受管 crawler 完成时结束或stop()同时停止所有爬取任务全部结束后完成。用 AsyncCrawlerRunner 并行运行当脚本需要自己管理 reactor 时用AsyncCrawlerRunner。并行写法是把两个crawl()的返回值都不等待最后await runner.join()两个 spider 同时跑、都结束后才往下执行。以下示例直接取自 docs/topics/practices.rstMySpider1/MySpider2需替换为你自己的 spider 类import scrapy from scrapy.crawler import AsyncCrawlerRunner from scrapy.utils.defer import deferred_f_from_coro_f from scrapy.utils.log import configure_logging from scrapy.utils.reactor import install_reactor from twisted.internet.task import react class MySpider1(scrapy.Spider): # 第一个 spider 的定义 ... class MySpider2(scrapy.Spider): # 第二个 spider 的定义 ... async def crawl(_): configure_logging({LOG_FORMAT: %(levelname)s: %(message)s}) runner AsyncCrawlerRunner() runner.crawl(MySpider1) runner.crawl(MySpider2) await runner.join() # 两个 spider 都结束后才完成 install_reactor() react(deferred_f_from_coro_f(crawl))这里的顺序要点configure_logging要在创建 runner 前调用因为AsyncCrawlerRunner本身不配置日志install_reactor()必须先于crawl()调用否则crawl()会抛出RuntimeError文档中给出的报错信息为 We expected a Twisted reactor to be installed but it isnt.。仓库测试脚本 tests/AsyncCrawlerRunner/multi_parallel.py 是同一模式的实际用例。用 AsyncCrawlerRunner 顺序运行多个 spider顺序执行只需对每次crawl()逐一await前一个 spider 完成后后一个才开始。同样来自 docs/topics/practices.rstimport scrapy from scrapy.crawler import AsyncCrawlerRunner from scrapy.utils.defer import deferred_f_from_coro_f from scrapy.utils.log import configure_logging from scrapy.utils.reactor import install_reactor from twisted.internet.task import react class MySpider1(scrapy.Spider): # 第一个 spider 的定义 ... class MySpider2(scrapy.Spider): # 第二个 spider 的定义 ... async def crawl(_): configure_logging({LOG_FORMAT: %(levelname)s: %(message)s}) runner AsyncCrawlerRunner() await runner.crawl(MySpider1) await runner.crawl(MySpider2) install_reactor() react(deferred_f_from_coro_f(crawl))对应测试脚本见 tests/AsyncCrawlerRunner/multi_seq.py。AsyncCrawlerProcess也可以做到顺序语义文档示例展示了在TWISTED_REACTOR_ENABLEDFalse时在同一进程内先后创建两个AsyncCrawlerProcess实例并各自start()前一个start()返回即爬取结束后才执行第二个。多 spider 同进程的限制以下几点直接来自文档决定你的配置方式日志设置和 reactor 设置不应因 spider 不同而取不同值pre-crawler 设置不能按 spider 分别定义。AsyncCrawlerProcess检测到后续 crawler 的 reactor 设置DNSCACHE_ENABLED、DNS_RESOLVER等与第一个 crawler 不一致时会发出警告并只使用第一个 spider 的值因为 reactor 被同进程所有 spider 共享见 scrapy/crawler.py 的create_crawler。其余所有设置包括并发与礼貌设置CONCURRENT_REQUESTS、CONCURRENT_REQUESTS_PER_DOMAIN、DOWNLOAD_DELAY都独立作用于每个 crawlerAutoThrottle 也分别对每个 crawler 限速。因此并行运行时文档建议把这些值除以 crawler 数量以保持对硬件和目标站点的总负载不变。由此推论在同一进程里把同一个 spider 跑多份并不会提升抓取能力只会乘倍地占满这些限额要爬得更快应在单个 crawler 上提高CONCURRENT_REQUESTS。Crawler.crawl()/crawl_async()每个 crawler 实例只能调用一次engine、extensions、stats等属性在爬取开始前读取会抛RuntimeError见 scrapy/crawler.py。如果你要在已有应用内而非独立脚本运行 spiderdocs/topics/practices.rst 的 Running spiders inside existing applications 一节给出了按应用类型已有 Twisted reactor、WSGI、ASGI的选择建议可与本文的 runner/process 用法对照使用。【免费下载链接】scrapyScrapy, a fast high-level web crawling scraping framework for Python.项目地址: https://gitcode.com/GitHub_Trending/sc/scrapy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询