【Scrapy爬虫系列2】性能调优



加快爬虫速度:

  • 在 settings.py 里把 TIMEOUT 设小点
  • 提高并发数( CONCURRENT_REQUESTS )
  • 瓶颈在 IO ,所以很有可能 IO 跑满,但是 CPU 没跑满,所以你用 CPU 来加速抓取其实是不成立的。不如开几个进程来跑死循环,这样 CPU 就跑满了
  • 在 setting.py 里面,可以把单 IP 或者单 domain 的 concurrent 线程数改成 16 或者更高,我这两天发现 16 线程对一般的网站来说根本没问题,而且 scrapy 自己的调度和重试系统可以保证每个页面都成功抓取。 
  • 至于分布式,前提还是被抓的服务器可以接受,在这个前提下,我有个比较笨的方法: 
  • 假定页面数是已知的,而且主页面的 url 是有规律的,例如 wordpress 的很多就是 domain.com/page/2000 这样的,同样的工程开 100 个进程,每个进程的 starturl 分别是 page/1 , page/21,page/41 这样的,然后自己实现一个 stopurl ,让这 100 个进程均摊 2000 个页面。一方面速度快(假定没有物理瓶颈),另一方面这 100 个进程相互独立,就算哪个进程挂掉,重跑的风险也被分摊了。
  • 动态页面最好找ajax传输的json数据,然后抓取其中需要的内容
  • 对于定向采集可以用正则取代xpath
  • 快代理还是不稳定的,如果使用额的是电信网络的话,可以试试路由重播更新IP
  • 快速的link extractor。python的SGMLParser实在是太慢了,使用SgmlLinkExtractor会让爬虫把大部分的时间都浪费在解析网页上,最好自己写一个link extractor(我们基于lxml写了一个,也可以用soup之类的库)。也可以用正则表达式来写link extractor,速度快,问题是不理解html语义,会把注释里的链接也包含进来。另外基于javascript重定向url也要在这里提取出来。
  • 默认启动的话,可以看到scrapy有10个线程。但是,进行download以及parse 等一般性操作的时候,都是单线程的——都是在同一个线程内。
  • 可以考虑gevent ,针对爬虫这种网络IO密集型的。效率会很高
  • 先去试试urllib和urllib2,熟悉一下爬虫的基本思维。然后熟悉了大概之后看看requests,这也是urllib\urllib2封装的,熟悉抓包和分析页面成分,了解POST、GET都是什么原理和实用
  • scrapy异步(做过几个项目了,挺好用的)
  • 分布式(暂时还没涉及),redis,scrapyd




参考:
  • 《scrapy抓取速度问题》https://www.v2ex.com/t/232070
  • 《同时运行多个scrapy爬虫的几种方法》http://www.cnblogs.com/rwxwsblog/p/4578764.html


你可能感兴趣的:(Python)