并发爬虫

Scrapy默认优化爬取特定的网站。这些站点通常只使用一个爬虫器来爬取, 虽然这不是必需的(例如, 一些 通用爬虫器可以处理任何抛给它们的站点)。

除了这种“集中爬虫”,还有一些常见的爬虫类型,包含了大量(可能是无限)的 domains , 并且只接受时间或者其他任意的约束,而不是当 domain 被爬取完或者没有其他请求时停止。 这种被称作“广泛爬虫”,是搜索引擎常用的一种典型爬虫。

这是一些广泛爬虫中常见的属性:

  • 有很多 domain(通常无边界)而不是一组特定的站点
  • 它们不一定要爬完整个 domain ,因为可能不会那样做,而是限制爬虫时间或者爬取的页数
  • 它们的逻辑简单 (和一些有着许多解析规则的非常复杂的爬虫器相比) 因为数据通常在一个单独的阶段进行POST请求
  • 同时爬取多个 domain , 让它们用更快的速度爬取而不受任何站点限制 (出于尊重单独的站 点用比较慢的方式爬取,但是很多站点的时候就要并行了)

正如上面说的, Scrapy 默认设置是优化集中爬虫, 而不是广泛爬虫。 不过,基于它的异步架构, Scrapy非常适合快速广泛爬虫。 本页总结了一些Scrapy广泛爬虫时需要注意的内容, 以及一些Scrapy配置的 建议,以便于有效地实现广泛爬虫。

如何使用 SCHEDULER_PRIORITY_QUEUE

Scrapy默认是优先使用 'scrapy.pqueues.ScrapyPriorityQueue' 队列进行调度。 它在单独 domain 的爬取表现是最好的。 反之在并行爬取不同的 domains 时表现一般。

优先队列的使用:

SCHEDULER_PRIORITY_QUEUE = 'scrapy.pqueues.DownloaderAwarePriorityQueue'

增加并发

并发意味着有许多讲求同时被处理。 有一个全局限制和单独 domain 的限制。

Scrapy默认的全局并发限制不适合并行爬虫多个不同 domains , 因此你需要增加。 增加多少取决于你的 CPU能给你的爬虫提供多少资源。 100 是个比较好的起点, 但是最好的方法是通过测试来找出 你的Scrapy在多少并发下会受到CPU限制。 最佳的情况是, 你的CPU利用率在 80-90% 之间.

增加全局并发:

CONCURRENT_REQUESTS = 100

增加Twisted IO线程池的最大量

目前Scrapy是通过纯种池以阻塞的方式进行DNS解析。 如果并发太高爬虫可能会变慢甚至DNS 解析超时而失败。 通过增加处理DNS查询的线程数量来解决. DNS队列将被更快地处理,加快建立连接和爬虫。

增加最大线程池的大小:

REACTOR_THREADPOOL_MAXSIZE = 20

设置你自己的DNS

如果你有多个爬虫进程和单个中心DNS, 它会像DoS攻击DNS服务器一样导致整个网络 变慢甚至阻塞你的计算机。 为了避免这样,设置你自己的DNS服务通过本地缓存和一些 上游大型DNS如OpenDNS 或 Verizon。

降低log等级

当进行广泛地爬虫时,你通常只对抓取速率和所有的错误感兴趣。 这些统计数据当Scrapy 的log等级是 INFO 时会被记录。为了节省CPU(和日志存储需求) 你不应该使用 DEBUG log等级。在开发时使用 DEBUG 等级应该没问题。

设置log等级:

LOG_LEVEL = 'INFO'

禁用 cookies

禁用cookies除非你 确实 需要。在进行大范围爬取时,通常不需要cookie(搜 索引擎会忽略它们), 它们通过节省CPU周期和减少内在占用来提高Scrapy爬虫的性能。

设置禁用cookies:

COOKIES_ENABLED = False

禁用重试

重试失败的HTTP请求会显著降低爬虫的速度, 尤其是由于站点原因造成的响应慢(或者失败)而造成的 超时错误导致过多重试,会阻止爬虫的生产力用到其他domains。

设置禁用重试:

RETRY_ENABLED = False

降低下载超时

除非你正从一个非常缓慢的链接爬虫(不该在大范围爬虫出现的情况)减少下载超时 以便快速丢弃卡住的情况,释放处理下一个请求的生产力。

设置降低下载超时:

DOWNLOAD_TIMEOUT = 15

禁止重定向

考虑禁用重定向, 除非你很有兴趣跟进它们。 当进行广泛爬虫时,通常会保存重定向 在以后的爬取时重新访问站点时解析它们。 这样也可以保持每批爬取请求的数量不变, 否则重定向的循环可能会导致爬虫在任意的domain中定向到太多的资源中去。

设置禁用重定向:

REDIRECT_ENABLED = False

启用爬取 “Ajax 页面爬取”

一些页面 (根据2013年的数据统计,高达1%) 声名它们为 ajax crawlable 。这 意味着他们只能用AJAX获得HTML中的内容。 页面可能用两种方法表示它:

  1. 在URL中使用 #! - 这是默认的方法;
  2. 使用特殊的meta标签 - 这个方法通常用于 “main”和”index”页面。

Scrapy 自动处理(1); 处理 (2) 使能 AjaxCrawlMiddleware:

AJAXCRAWL_ENABLED = True

当进行广泛的爬虫时经常会爬取很多”index”页面; AjaxCrawlMiddleware 帮助正确地爬取它们。 因为它会有一些性能开销所以默认情况下它是关闭的。 而且在集中爬取时启用它也没什么用。