优化scrapy的一点心得

以下方法均是在网络带宽不是瓶颈的前提下得出的一点小经验。在这里拿出来和大家分享。

Scrapy配置

CONCURRENT_REQUESTS 最大并发请求数
CONCURRENT_REQUESTS_PER_DOMAIN 相同域的最大并发请求
CONCURRENT_REQUESTS_PER_IP 相同IP最大并发请求

以上的数字往大了写就好。
但有可能因为系统(linux)的限制会因scrapy无法占用系统过多资源(比如我就在一开始遇到了,文件打开过多的报错)而报告大量警告。
这两篇博文也许能帮到大家:Increase “Open Files Limitlinux修改最大文件链接数open files/ulimit -n

尽量不要在scrapy中进行CPU密集型与磁盘I/O密集型操作

!!(╯’ – ‘)╯︵ ┻━┻ (掀桌子) ┬─┬ ノ( ‘ – ‘ノ) {摆好摆好) (╯°Д°)╯︵ ┻━┻(再他妈的掀一次)
这俩都不要,那就是啥都不让干了呗?不,还可以对内存进行操作。
在scrapy中进行cpu与磁盘I/O密集操作的话会极大的拖慢scrapy的抓取速度。
信息的提取与存储尽量给到其他脚本,使其与scrapy并行,避免因等待写数据库或数据,拖累其下载任务的执行。
那么数据怎么暂存并传递到其他脚本呢?

使用内存数据库

试了下处理请求响应后不返回item,结果爬取速度暴涨!我就想到了内存数据库。
通过内存数据库的使用,避免在scrapy内大量操作硬盘数据库,我在使用内存数据库(Redis)后scrapy每分钟抓取速度为原来的 6 倍左右。
并且因为避免了硬盘瓶颈,从而可以通过下一条方法进一步提高抓取速度。
这里在提一句,尽量使用更少的sql语句完成对更多数据操作,比如,每隔一段时间,再从内存数据库中取出批量的数据,并且每个表的插入或更新只使用一条语句进行批量的插入与更新。

多开scrapy充分利用CPU

从我目前的实践来看一个scrapy只能利用一个线程,如果你的scrapy并没有把带宽充分利用,并且从CPU的使用率来看只占用了一个线程,那可以尝试多个scrapy并行。几线程CPU开几个,此时top中可以看到每个scrapy进程的cpu占用都为99左右,过多的话会因为争抢资源反而减慢爬取速度。

scrapy不要运行过长时间,要运行一段时间后重开你的scrapy

可能是因为内存泄漏,或它在存储一些信息,scrapy占用的内存会越来越大,并且越来越慢,尤其是到了虚拟内存上阵的时候…
所以最好是通过一个master脚本,为每个scrapy分配较为少量的任务,并在其完成任务后分配新任务,并开启新的scrapy抓取。

结尾

以上就是我最近使用scrapy发觉到的优化方法。如果大家还有什么更好的方法,欢迎留言。如果哪里说得不对,欢迎拍砖。