使用 Scrapy-Redis 实现分布式爬虫如何优雅保持调度池能够满足多台机器的同时爬取?为何调度池容易为空?

  1. 问题:在项目中使用了 RedisCrawlSpider 的爬虫模板,实现的是双向爬取,即一个 Rule 处理水平的下一页 url 爬取,一个 Rule 处理垂直的详情页 url 爬取。然后分布式爬取的效果是,即使有多台机器一起跑,仍然是只有当前页和当前页相关的详情页爬取完之后才爬取下一页,在网站有反爬虫措施的情况下,效果可想而知,分布式爬取的效率基本没有体现出来。
  2. 想法:后来通过尝试发现,在爬取过程中,往 Redis 数据库中的 name:start_urls 添加请求链接,也能够被调度去请求,因此就有了先往 name:start_urls 添加足够的请求链接这样就有足够的调度池分配了,应该可以避免出现有些机器处于等待调度的状态。
  3. 做法:于是我就将本来水平爬取页码 url 的部分独立出来,将生成的每一页的 url 存到 name:start_urls 中,果然这样多台主机有了足够调度池进行分配,确实爬取效率就完全体现出来了。

不过,我很好奇大家是否有遇到我的这种问题,如果有,大家的解决方案是怎么样的呢,有没有更好的解决方案呢?因为我这种方式还需要单独独立一个生成 url 并存入 name:start_urls 的程序,感觉做法不是很优雅方便,虽然已经是个人能想到的比较好的解决方案了。

阅读 2.8k
1 个回答

默认情况下,Scrapy使用 LIFO 队列来存储等待的请求。简单的说,就是 深度优先顺序 。深度优先对大多数情况下是更方便的。如果您想以 广度优先顺序 进行爬取,你可以设置以下的设定:

DEPTH_PRIORITY = 1
SCHEDULER_DISK_QUEUE = 'scrapy.squeue.PickleFifoDiskQueue'
SCHEDULER_MEMORY_QUEUE = 'scrapy.squeue.FifoMemoryQueue'

参考文档

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进