scrapy基于twisted异步IO框架,downloader是多线程的。但是,由于python使用GIL(全局解释器锁,保证同时只有一个线程在使用解释器),这极大限制了并行性,在处理运算密集型程序的时候,Python的多线程效果很差,而如果开多个线程进行耗时的IO操作时,Python的多线程才能发挥出更大的作用。(因为Python在进行长时IO操作时会释放GIL)所以简单的说,scrapy是多线程的,不许要再设置了,由于目前版本python的特性,多线程地不是很完全,但实际测试scrapy效率还可以
因为Python GIL的存在,scrapy无论如何设置都是单线程的。Scrapy里默认是10线程的设置是指的Twisted的线程,可以用来并行处理DNS之类的。但上面这些都不重要,因为爬虫是IO密集型的操作,所以只要有并发就可以了,无论是利用协程,callback还是其他方式实现并发。所以你要修改的不是线程数目而是Scrapy里request的并行数,只要这个数目大了一般速度都会增快,如果并行大了速度却没有提升,可能是DOWNLOAD_DELAY太大了。
所以,提升scrapy爬取效率的方式有:
1)在 settings.py 里把 DOWNLOAD_DELAY设置小一点(保证IP不被封的情况下)
2)提高并发数( CONCURRENT_REQUESTS ) #也并不是越多越好,CPU调度有上限
3)瓶颈在 IO ,所以很有可能 IO 跑满,但是 CPU 没跑满,所以你用 CPU 来加速抓取其实是不成立的。不如开几个进程来跑,这样 CPU 就跑满了
4)在 setting.py 里面,可以把单 IP 或者单 domain 的 concurrent 线程数改成 16 或者更高,16 线程对一般的网站来说根本没问题,而且 scrapy 自己的调度和重试系统可以保证每个页面都成功抓取
5)动态页面最好找ajax传输的json数据,然后抓取其中需要的内容
6)对于定向采集可以用正则取代xpath(或BS)
7)代理
8)可以考虑gevent ,针对爬虫这种网络IO密集型的。效率会很高
9)搭建分布式爬虫