scrapy 调优

Scrapy 设置中 CONCURRENT_REQUESTS 及 DOWNLOAD_DELAY 等几个相关参数的作用

准备工作
实验验证
只单独设置并发数CONCURRENT_REQUESTS或者CONCURRENT_REQUESTS_PER_DOMAIN
同时设置CONCURRENT_REQUESTS和CONCURRENT_REQUESTS_PER_DOMAIN
不开启并发,同时将spider中的请求队列改为只向一个地址发送请求,测试下载DELAY
开启并发,请求队列变成对两个地址的请求,测试下载DELAY
总结
Scrapy的默认设置中,有几个关于并发请求及下载延迟的参数,这几个参数的设置,既影响请求效率,同时关乎对方服务器的压力大小。

相关的几个参数:

CONCURRENT_REQUESTS
默认值:16
Scrapy下载器发送的最大并发请求数。

CONCURRENT_REQUESTS_PER_DOMAIN
默认值:8
针对某一个域名的最大并发请求数。

CONCURRENT_REQUESTS_PER_IP
默认值:0
针对某一ip的最大并发请求数。如果此项非0的话,它的优先级高于CONCURRENT_REQUESTS_PER_DOMAIN。也就是说此时的并发数量限制是基于ip的,而非域名。
同时这个设置也会影响到DOWNLOAD_DELAY,如果CONCURRENT_REQUESTS_PER_IP非0,下载延迟会基于ip,而非域名。

DOWNLOAD_DELAY
默认值:0
每个请求间的下载延迟,单位为秒。同时受RANDOMIZE_DOWNLOAD_DELAY参数(默认开启)影响,下载延迟并不会是设定的固定值,而是在 0.5DOWNLOAD_DELAY~1.5DOWNLOAD_DELAY区间内。
默认是针对同一域名的每个请求设置DELAY,如果CONCURRENT_REQUESTS_PER_DOMAIN非0,下载延迟会基于ip,而非域名。

这里通过实验的方式,验证这几个参数的表现,以及同时设置某几个参数的影响。为了能直观准确的看到请求时间差,全程将RANDOMIZE_DOWNLOAD_DELAY设置为False,也就是固定下载延迟,而非在区间内波动。

准备工作
使用flask写一个简易的服务端程序,同时在两台机器上运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import time
from flask import Flask, make_response

app = Flask(name)

@app.route(’/’)
def index():
time.sleep(10)
response = make_response(‘Hello World!’)

return response

if name == ‘main’:
app.run(host=‘0.0.0.0’, port=“9999”, debug=True, threaded=True)
创建一个scrapy项目,其中spider脚本如下,在请求队列中均匀分布两个ip的请求:

1
2
3
4
5
6
7
8
9
10
11
import scrapy
from itertools import chain

class TestSpider(scrapy.Spider):
name = ‘test’
urls1 = [‘http://0.0.0.0:9999/’ for i in range(20)]
urls2 = [‘http://123.206.38.21:9999/’ for j in range(20)]
start_urls = list(chain.from_iterable(zip(urls1, urls2)))

def parse(self, response):
    print(response.body)

实验验证
根据上文,CONCURRENT_REQUESTS_PER_DOMAIN和CONCURRENT_REQUESTS_PER_IP两个参数是覆盖关系,所以这里只以其中任何一个作为参考即可,这里选择CONCURRENT_REQUESTS_PER_DOMAIN。

只单独设置并发数CONCURRENT_REQUESTS或者CONCURRENT_REQUESTS_PER_DOMAIN
1
CONCURRENT_REQUESTS = 10

或者

1
CONCURRENT_REQUESTS_PER_DOMAIN = 2

结果显而易见,CONCURRENT_REQUESTS限制了总并发数,CONCURRENT_REQUESTS_PER_DOMAIN分别对单个域名的并发数起到了限制。

同时设置CONCURRENT_REQUESTS和CONCURRENT_REQUESTS_PER_DOMAIN
1
2
CONCURRENT_REQUESTS = 6
CONCURRENT_REQUESTS_PER_DOMAIN = 4

在同时设置CONCURRENT_REQUESTS和CONCURRENT_REQUESTS_PER_DOMAIN时,两者不存在覆盖关系,而是共同对并发数起到了限制,两者的交集决定了最大并发数。

不开启并发,同时将spider中的请求队列改为只向一个地址发送请求,测试下载DELAY
1
2
CONCURRENT_REQUESTS = 1
DOWNLOAD_DELAY = 5

响应间隔为10秒,貌似设置的DELAY没起作用的样子。
其实不然,这里存在一个误区,由于平时正常访问网站几乎是秒回响应,DELAY时间远大于从请求到返回响应的这段时间,所以看不出端倪。
而这里服务器的处理时间为10秒,大于DELAY时间。假设将请求到响应的完整流程看做一个事务,DOWNLOAD_DELAY并没有作用到这个完整事务上,而是作用到了每个请求上,在每个请求发送之后,DELAY即开始计数,计数到设置的DELAY时间点,发送下一个请求。
这里的DELAY时间为5秒,虽然在响应未返回就计数完成,可以发送请求,但由于并发数为1,所以只能等待收到响应后再发送下一次的请求。

设置大于服务器处理时间的DELAY,测试下载DELAY

1
2
CONCURRENT_REQUESTS = 1
DOWNLOAD_DELAY = 13

证实了上面的结论,在21:48:05发送第一个请求后,即开始计数,设置的DELAY为13秒,因此到21:48:18发送下一个请求,21:48:28收到响应,以此类推…

开启并发,请求队列变成对两个地址的请求,测试下载DELAY
1
2
CONCURRENT_REQUESTS = 10
DOWNLOAD_DELAY = 5

在第一个响应之后,每隔5秒收到一个响应。验证了上一步的结论,在发送请求后即开始DELAY计数,到达设定的时间后就会发送下一个请求。
两个地址的响应是同时返回的,也就是说DOWNLOAD_DELAY 针对的是单个域名的请求,而不是将所有请求一视同仁的DELAY。

总结
在同时设置CONCURRENT_REQUESTS和CONCURRENT_REQUESTS_PER_DOMAIN时,两者不存在覆盖关系,而是共同对并发数起到了限制,两者的交集决定了最大并发数。
DOWNLOAD_DELAY只作用于单个地址下的请求,进行DELAY;下载间隔在发送请求后即开始计数,到达设定值发送下一次请求,无关响应。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值