我是靠谱客的博主 魁梧超短裙,最近开发中收集的这篇文章主要介绍解决Scrapy性能问题——案例六(下载器中请求太少),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

症状:增加了CONCURRENT_REQUESTS,但是下载器并没有得到充分的利用,调度器也是空的。

示例:首先来运行一个没有这种问题的例子,把响应时间设置成1s,这样可以简化下载器吞吐量的计算:T = N/S = N/1 = CONCURRENT_REQUESTS

$ time scrapy crawl speed -s SPEED_TOTAL_ITEMS=500 
-s SPEED_T_RESPONSE=1 -s CONCURRENT_REQUESTS=64
s/edule d/load scrape p/line done mem
436 64 0 0 0 0
...
real 0m10.99s

此时的下载器是满负荷工作的,总共花费的时间是11s,和模型计算出来的结果相符合:这里写图片描述s。

现在,还是这个程序(源码参见这里),这次不从列表中获取初始URL,而是给出一个索引页,从索引页中自己来提取20个URL:

$ time scrapy crawl speed -s SPEED_TOTAL_ITEMS=500 
-s SPEED_T_RESPONSE=1 -s CONCURRENT_REQUESTS=64 
-s SPEED_START_REQUESTS_STYLE=UseIndex
s/edule d/load scrape p/line done mem
0 1 0 0 0 0
0 21 0 0 0 0
0 21 0 0 20 0
...
real 0m32.24s

显然这次和之前的例子不一样,不知何故,下载器中的请求数量比它的最大容量要小,吞吐量为T = N/(S - 这里写图片描述) = 500/(32.2 - 3.1) = 17个请求每秒。

讨论:看一下d/load栏就知道下载器没有被充分利用,这是因为我们并没有给它提供足够的URL。整个抓取过程生产URL的速度没有它消费URL的速度快。在本例中,从每个索引页可以获得20 + 1(下一个索引页)个URL,这样的吞吐量不可能达到每秒超过20个请求,因为获取URL的速度很慢。这种问题比较微妙。很容易就被忽视了。

解决方法:如果每个索引页有多于一个的下一页的链接,我们就可以使用这些链接来加速URL的产生。如果能找到含有更多的结果(例如50个)的索引页那就更好了。可以通过一些仿真来观察程序的性能:

$ for details in 10 20 30 40; do for nxtlinks in 1 2 3 4; do
time scrapy crawl speed -s SPEED_TOTAL_ITEMS=500 -s
SPEED_T_RESPONSE=1 
-s CONCURRENT_REQUESTS=64 -s
SPEED_START_REQUESTS_STYLE=UseIndex 
-s SPEED_DETAILS_PER_INDEX_PAGE=$details 
-s SPEED_INDEX_POINTAHEAD=$nxtlinks
done; done

这里写图片描述

在图12中可以看到吞吐量随着这两个参数而变化的情形。在到达系统的限制之前,我们可以观察到吞吐量是随着这两个参数而线性增长的。你也可以重新排序一下爬虫的Rule来做个实验。如果你使用的是LIFO(默认)的顺序,那么如果你把提取索引页的请求放在Rule列表中的最后一个,以便调度器分配请求的时候把对索引页请求的顺序排在前面,这样会有一个吞吐量方面的微小的提升。你也可以把把索引页的请求设置一个比较高的优先级,这两种方法都不会有太过显著的提升,但是可以通过设置SPEED_INDEX_RULE_LAST=1SPEED_INDEX_HIGHER_PRIORITY=1来分别尝试一下。要记住的一点是,这些解决方法都是先下载索引页,这样就能在调度器中产生很多URL,不过也会导致内存的需求增加。这些方法还有一个问题,由于是LIFO或者索引页高优先级的模式,爬虫会先处理完对所有索引页的请求,在抓取完所有的索引页之前不会产生太多的结果,如果索引页比较少,那还可以,但是如果索引页比较多,那就不是我们希望的结果了。

对于上面的问题,可以通过把索引页分成几个部分来解决。这就要求你能在程序中使用不只一个初始的索引URL了,而且这些初始的索引URL相互之间要离得比较远才行。例如,如果有100个索引页,那么就可以选择1和51这两个索引页当做初始的URL。这样爬虫就能以两倍的速度来遍历索引页。可以使用-s SPEED_INDEX_SHARDS设置项来仿真一下:

$ for details in 10 20 30 40; do for shards in 1 2 3 4; do
time scrapy crawl speed -s SPEED_TOTAL_ITEMS=500 -s
SPEED_T_RESPONSE=1 
-s CONCURRENT_REQUESTS=64 -s
SPEED_START_REQUESTS_STYLE=UseIndex 
-s SPEED_DETAILS_PER_INDEX_PAGE=$details -s
SPEED_INDEX_SHARDS=$shards
done; done

这个结果显然比之前的要好,如果能使用的话,最好使用这个方法来解决下载器中请求不够的问题。

最后

以上就是魁梧超短裙为你收集整理的解决Scrapy性能问题——案例六(下载器中请求太少)的全部内容,希望文章能够帮你解决解决Scrapy性能问题——案例六(下载器中请求太少)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部