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)搭建分布式爬蟲