广泛爬取¶
Scrapy 默认设置针对爬取特定网站进行了优化。这些网站通常由单个 Scrapy 爬虫处理,尽管这并不是必须或要求的(例如,有一些通用爬虫可以处理任何给定的网站)。
除了这种“聚焦爬取”之外,还有另一种常见的爬取类型,它覆盖了大量(可能无限)的域名,并且仅受时间或其他任意限制的约束,而不是在域名爬取完成或没有更多请求可执行时停止。这些被称为“广泛爬取”,是搜索引擎通常使用的爬虫。
这些是广泛爬取中常见的一些属性:
他们爬取许多域名(通常是无限制的),而不是特定的网站集合
他们不一定完全爬取域名,因为这样做可能不切实际(或不可能),而是通过时间或爬取的页面数量来限制爬取。
它们在逻辑上更简单(与具有许多提取规则的非常复杂的爬虫相比),因为数据通常在单独的阶段进行后处理
它们同时爬取许多域名,这使得它们能够通过不受任何特定站点限制(每个站点都被缓慢爬取以尊重礼貌,但许多站点是并行爬取的)来实现更快的爬取速度。
如上所述,Scrapy 的默认设置是针对聚焦爬虫优化的,而不是广泛爬虫。然而,由于其异步架构,Scrapy 非常适合执行快速的广泛爬虫。本页总结了一些在使用 Scrapy 进行广泛爬虫时需要注意的事项,以及为了实现高效的广泛爬虫而需要调整的 Scrapy 设置的具体建议。
使用正确的SCHEDULER_PRIORITY_QUEUE¶
Scrapy的默认调度器优先级队列是'scrapy.pqueues.ScrapyPriorityQueue'。
它在单域爬取时效果最佳。在并行爬取许多不同域时效果不佳。
要应用推荐的优先级队列,请使用:
SCHEDULER_PRIORITY_QUEUE = "scrapy.pqueues.DownloaderAwarePriorityQueue"
增加并发性¶
并发性是指并行处理的请求数量。有一个全局限制(CONCURRENT_REQUESTS),并且可以针对每个域(CONCURRENT_REQUESTS_PER_DOMAIN)或每个IP(CONCURRENT_REQUESTS_PER_IP)设置额外的限制。
注意
调度器优先级队列 推荐用于广泛爬取 不支持
CONCURRENT_REQUESTS_PER_IP.
Scrapy中的默认全局并发限制不适合并行爬取许多不同的域名,因此您可能需要增加它。增加多少取决于您的爬虫将有多少可用的CPU和内存。
一个好的起点是 100:
CONCURRENT_REQUESTS = 100
但最好的方法是通过一些试验来确定在什么并发情况下你的Scrapy进程会受到CPU限制。为了获得最佳性能,你应该选择一个CPU使用率在80-90%的并发级别。
增加并发性也会增加内存使用量。如果内存使用量是一个问题,您可能需要相应地降低全局并发限制。
增加Twisted IO线程池的最大大小¶
目前Scrapy以阻塞方式使用线程池进行DNS解析。在高并发级别下,爬取可能会变慢,甚至因DNS解析器超时而失败。可能的解决方案是增加处理DNS查询的线程数量。DNS队列将更快地被处理,从而加快连接的建立和整体爬取速度。
要增加最大线程池大小,请使用:
REACTOR_THREADPOOL_MAXSIZE = 20
设置您自己的DNS¶
如果您有多个爬虫进程和单一的中央DNS,它可能会像对DNS服务器的DoS攻击一样,导致整个网络变慢甚至阻止您的机器。为了避免这种情况,请设置您自己的带有本地缓存和上游到一些大型DNS(如OpenDNS或Verizon)的DNS服务器。
降低日志级别¶
在进行广泛爬取时,通常只对爬取速率和发现的错误感兴趣。这些统计数据在使用INFO日志级别时由Scrapy报告。为了节省CPU(和日志存储需求),在生产环境中执行大规模广泛爬取时不应使用DEBUG日志级别。在开发(广泛)爬虫时使用DEBUG级别可能是可以的。
要设置日志级别,请使用:
LOG_LEVEL = "INFO"
禁用重试¶
重试失败的HTTP请求可能会显著减慢爬取速度,特别是在网站响应非常慢(或失败)时,从而导致超时错误,这些错误会被不必要地多次重试,阻止爬虫能力被重新用于其他域名。
要禁用重试,请使用:
RETRY_ENABLED = False
减少下载超时¶
除非你正在从一个非常慢的连接进行爬取(对于大规模爬取来说不应该如此),否则请减少下载超时时间,以便快速丢弃卡住的请求,并释放容量以处理下一个请求。
要减少下载超时,请使用:
DOWNLOAD_TIMEOUT = 15
禁用重定向¶
考虑禁用重定向,除非您有兴趣跟踪它们。在进行广泛爬取时,通常会保存重定向并在稍后的爬取中重新访问站点时解析它们。这也有助于保持每次爬取批次的请求数量恒定,否则重定向循环可能会导致爬虫在特定域名上投入过多资源。
要禁用重定向,请使用:
REDIRECT_ENABLED = False
启用“可爬取的Ajax页面”的爬取¶
一些页面(根据2013年的经验数据,最多1%)声明自己为可抓取的AJAX页面。这意味着它们提供了通常只能通过AJAX获取的内容的纯HTML版本。页面可以通过两种方式表明这一点:
通过在URL中使用
#!- 这是默认的方式;通过使用一个特殊的meta标签 - 这种方式用于“主页”、“索引”网站页面。
Scrapy 自动处理 (1);要处理 (2),请启用 AjaxCrawlMiddleware:
AJAXCRAWL_ENABLED = True
在进行广泛爬取时,通常会爬取大量的“索引”网页; AjaxCrawlMiddleware 有助于正确爬取这些网页。 它默认是关闭的,因为它有一定的性能开销, 并且在针对特定目标的爬取中启用它没有太大意义。
按BFO顺序爬取¶
在广泛的爬取中,页面爬取往往比页面处理更快。因此,未处理的早期请求会一直留在内存中,直到达到最终深度,这可能会显著增加内存使用量。
Crawl in BFO order 改为以节省内存。
注意内存泄漏¶
安装特定的Twisted反应器¶
如果爬取超出了系统的能力范围,您可能想尝试通过TWISTED_REACTOR设置安装一个特定的Twisted反应器。