在编程语言的世界里,python似乎被贴上了做爬虫的一个标签,强而有力。而scrapy做为另一个老牌的开源项目,更是大规模抓取不可或缺的一个重要力量。纵使scrapy依旧有一些长期无法解决的诟病,但是他在抓取过程帮程序员解决的一系列的细节问题,还是有无以伦比的优势。

缺点

1. 重量级

scrapy依赖于twisted,而twisted是python世界的出名的重量级框架。要读懂scrapy的源码,必须先了解twisted(deffered,reactor)的工作原理,读懂twisted的源码,这样一切看起都非常困难。

2. 内存

为了防止重复对同一个url抓取,避免无限递归的遍历url,scrapy把所有处理过的request(包括method,url,headers)放到内存当中,如果spider处理的request够多的话,spider占用的内存是惊人的。

解决方法

  1. 必要的时,将一个大型spider(可预计抓取的url过多)拆分成多个spider。

  2. bloom,以空间换取准确性的一种去重算法。settings.py里配置DUPEFILTER_CLASS = 'scrapy.dupefilter.RFPDupeFilter',用自己实现的bloom算法覆盖即可。要注意的是,bloom是牺牲了准确性开换取空间开支小的算法,在内存能够胜任,就显得多此一举。

3. xpath的容错(并不是scrapy独有)

经常会遇到解析一些非标准的html,在浏览器会对他们进行容错处理,而不会影响到页面展现。但是用xpath就要了命了,而且通常还不容易察觉。解决办法

  1. 将整个html转化成标准的xml,在用xpath解析。比如<div>xx</div></div>,这个时候就要想办法把第二个</div>去掉。

  2. 用re解析抽取结构化信息。不推荐用re,不是因为在这种场景下效果不好,而是因为用正则会增加spider的维护成本,具体的下面会提到。

 

优点

理论只是实践基础和指导原则,要知道理论到实践还是有很多路要走的。本人比较反对将重复造轮子的东西轻易的拿到生产上去实践。spider不仅仅是把内容结构化,而是在各个细节处理上都很全面。

1. 智能编码

scrapy会从meta中自动提取里涉及到的编码,如果没有则尝试gb2312,utf-8编码,最后还不行的话,就用自定义的编码DEFAULT_RESPONSE_ENCODING。虽然这种方式不能完成正确,也能保证90%(我实践中得到的结果)以上的正确性。

2. 灵活的pipeline

pipeline以管道的方式处理item,比如说item再加工,过滤,持久化都可以再这里处理。可以定义多个pipeline,对item做不同的处理。如果在item中有个image字段,可以先用MediaPipeline处理过,将图片下载到本地,再讲item插入到数据库。

3. 强大的xpath

scrapy是xpath作为解析工具,之前提到的也可以用正则但是不推荐,一个很重要的原因是,xpath维护,可读性要比正则强太多。spider的维护一项持久而耗时的工作,特别是一些静态网站,都是通过cms系统发布,这样会导致网站的结构,样式调整的比较频繁,用re会陷入无尽的烦恼当中。而xpath固然也会有种问题,但是良好的可读性,会让维护成本成倍的降低。

4. 处理http请求的各种细节

  1. 设置抓取时间间隔,在spider中设置download_delay=x(单位是秒)

  2. 配置代理,settings中增加HttpProxyMiddleware(默认),设置系统代理

  3. 配置自定义代理

1 import base64 
2 
3 class ProxyMiddleware(object):
4     def process_request(self, request, spider):
5         request.meta['proxy'] = "http://YOUR_PROXY_IP:PORT"
6         proxy_user_pass = "USERNAME:PASSWORD"
7         encoded_user_pass = base64.encodestring(proxy_user_pass)
8         request.headers['Proxy-Authorization'] = 'Basic ' + encoded_user_pass

  也可以将代理配置成随机的,只需要在上面代码中稍作处理。

  4. http code的处理,正常情况下,scrapy的response只处理20x,设置handle_httpstatus_list = [301,302,204,206,404,500]

  5. retry机制,由于网络或者对方服务器的原因,对url重复处理是非常有必有,spider中设置RETRY_TIMES,RETRY_HTTP_CODES

  6. 模拟浏览器行为,设置user-agent

  7. 设置默认headers, DEFAULT_REQUEST_HEADERS

  8. cookies处理,开启COOKIES_DEBUG=True后,可以再Request中带上cookies

yield Request(url='http://www.douban.com',cookies={'session':'xxxx'})

  等等吧,太多了。

5. 对https,ftp等协议支持,使用过程和http一样。

6. 强大的监控,日志系统

默认开启TELNETCONSOLE_ENABLED = 1,WEBCONSOLE_ENABLED = 1具体的可以看文档。一般的情况下,会查看spider close的日志,整个spider的运行状态都查看到

7. 支持json,jsonlines,csv,xml,marshal,pickle导出

 

不写了,下一篇继续