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 - 如何启动同一个蜘蛛进程的多个实例?的主要内容,如果未能解决你的问题,请参考以下文章