Scrapy运行的有telnet服务,我们可以通过这个功能来得到一些性能指标。通过telnet命令连接到6023端口,然后就会得到一个在爬虫内部环境的Python命令行。要小心的是,如果你在这里运行了一些阻塞的操作,比如time.sleep()
,正在运行的爬虫就会被中止。通过内建的est()
函数可以打印出一些性能指标。
打开第一个命令行,运行以下代码:
$ pwd
/root/book/ch10/speed
$ ls
scrapy.cfg speed
$ scrapy crawl speed -s SPEED_PIPELINE_ASYNC_DELAY=1
INFO: Scrapy 1.0.3 started (bot: speed)
...
现在先不用管scrapy crawl speed
和它的参数的意义是什么,之后的章节会解释。在第二个命令行运行:
$ telnet localhost 6023
>>> est()
...
len(engine.downloader.active) : 16
...
len(engine.slot.scheduler.mqs) : 4475
...
len(engine.scraper.slot.active) : 115
engine.scraper.slot.active_size : 117760
engine.scraper.slot.itemproc_size : 105
在这里我们忽略了
dqs
指标,如果你启用了持久化支持的功能,亦即设置了JOBDIR
设置项,你也会得到非零的dqs
(len(engine.slot.scheduler.dqs)
)值,这时候就应当把dqs
加到mqs
上去,以便后续的分析。
先来看一下这个例子中的指标都代表着什么。mqs
意味着在调度器中有很多请求等待处理(4475个请求)。这是没问题的。len(engine.downloader.active)
表示着现在有16个请求正被下载器下载。这和我们设置的CONCURRENT_REQUESTS
值是一样的,所以也没问题。len(engine.scraper.slot.active)
告诉我们现在正有115个响应在scraper中处理,这些响应的总的大小可以从engine.scraper.slot.active_size
指标得到,共是115kb。除了这些响应,pipeline中正有105个Item
被处理——从engine.scraper.slot.itemproc_size
中得知,也就是说,还有10个正在爬虫中进行处理。总的来说,可以确定下载器就是系统的瓶颈,因为在下载器之前有很多请求(mqs
)在队列中等待处理,下载器已经被充分地利用了;在下载器之后,我们有一个或多或少比较很稳定的工作量(可以通过多次调用est()
函数来证实这一点)。
另一个信息来源是stats
对象,它一般情况下会在爬虫运行结束后打印出来。而在telnet中,我们可以随时通过stats.get_stats()
得到一个dict
对象,并用p()
函数打印出来:
$ p(stats.get_stats())
{'downloader/request_bytes': 558330,
...
'item_scraped_count': 2485,
...}
item_scraped_count
代表着目前为止已经有多少Item
被抓取到,并可以通过stats.get_value('item_scraped_count')
得到该值。