Scrapy - 如何启动同一个蜘蛛进程的多个实例?

Posted

技术标签:

【中文标题】Scrapy - 如何启动同一个蜘蛛进程的多个实例?【英文标题】:Scrapy - How to initiate multiple instances of same spider process? 【发布时间】:2016-02-14 21:47:22 【问题描述】:

我在启动同一个蜘蛛的多个实例时卡住了。我想像 1 个蜘蛛实例的 1 个 url 一样运行它。我必须处理 50k 网址,为此我需要为每个网址启动单独的实例。在我的主要蜘蛛脚本中,我设置了 7 分钟的封闭式超时,以确保我不会长时间爬行。请看下面的代码:

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
import urlparse

for start_url in all_urls:
    domain = urlparse.urlparse(start_url).netloc
    if domain.startswith('ww'):
        domain = domain.split(".",1)[1]

    process = CrawlerProcess(get_project_settings())
    process.crawl('textextractor', start_url=start_url,allowed_domains=domain)
    process.start()

它完全为第一个 url 运行,之后当第二个 url 被传递时,它会给出以下错误:

raise error.ReactorNotRestartable()
ReactorNotRestartable

请建议我应该怎么做才能让它为同一个蜘蛛的多个实例运行。另外,我正在考虑使用线程一次启动多个scrapy实例。这会是一个很好的方法吗?

【问题讨论】:

这件事有什么更新吗? ReactorNotRestartable error in while loop with scrapy的可能重复 你是怎么解决的——面临类似的问题。我用 CrawlerRunner 遍历了我所有的 url,但结果不符合预期。一些 url 被抓取,另一些被限制抓取,而另一些则根本不被抓取。当我只用一个蜘蛛单独运行每个 url 时,结果符合预期。它让我发疯! 【参考方案1】:

这个怎么样

process = CrawlerProcess(get_project_settings())

for start_url in all_urls:
    domain = urlparse.urlparse(start_url).netloc
    if domain.startswith('ww'):
        domain = domain.split(".",1)[1]
    process.crawl('textextractor', start_url=start_url,allowed_domains=domain)

process.start()

【讨论】:

furas 我用你的解决方案进行了测试,但它没有提供正确的结果。这个解决方案确实启动了多个实例而没有给出ReactorNotRestartable 错误,但它只完全抓取最后传递的 url,它确实抓取了其他 url开始爬行,但不要爬行超过 1 个 url 并完成蜘蛛。我已经分别检查了这些 url,它们确实返回了很多爬取的数据。另外,正如我所提到的,我必须为 50k url 执行此操作,这样做是否意味着我将立即开始为 50k url 爬行过程?这看起来是个好方法吗?【参考方案2】:

您是否有特定原因要启动 50k 个蜘蛛实例? Twisted 默认只允许单个实例运行(除非你杀死整个进程并重新启动)

其次,“1 个蜘蛛实例的 1 个 url”会导致巨大的内存开销。您应该考虑将所有 url 传递给同一个实例。

【讨论】:

【参考方案3】:

就我而言,您的目的不是必需的。因为scrapy中的蜘蛛,你产生的每个request都是异步的。不需要创建多个实例。

加速爬虫的方法是Increase concurrency

而处理50k个url的方式是spider-arguments

【讨论】:

以上是关于Scrapy - 如何启动同一个蜘蛛进程的多个实例?的主要内容,如果未能解决你的问题,请参考以下文章

在 Celery 任务中运行 Scrapy 蜘蛛

如何在单个 Scrapy 项目中为不同的蜘蛛使用不同的管道

单个 Scrapy 项目与多个项目

在 Scrapy 中在一个蜘蛛中有多个解析方法是不是正确?

Scrapy运行2个蜘蛛,使用一个进程将输出到2个不同的文件(AWS Lambda)

如何让我可以用一只scrapy蜘蛛一致地绕过一系列网站?