scrapy经验总结

来源:互联网 发布:linux安装gz文件 编辑:程序博客网 时间:2024/06/01 08:47

这几天学习了一下scrapy爬虫,总结一下一些经验教训。

  1. 安装上,windows反而很顺利,在搬瓦工的VPS上安装时需要注意一些问题。首先是升级python到2.7版,这是scrapy需求的,这个问题网上有很多现成的教程,不需要重复了。
  2. python升级之后,仍然可能安装失败,需要安装一些python开发库,主要是下面这些:
  3. 用scrapy建立工程之后,在spiders目录下添加python文件编写爬虫时,最好不要让文件名和工程名一样,否则你从上一级目录导入自定义的item类时会出问题。
  4. scrapy shell在cygwin的terminal下运行有问题,改回windows的cmd环境就正常了。
  5. 爬虫代码中,如果需要调试信息,用logging模块而不是print,print要等到爬虫运行完之后才会打印,而logging是即时的。
  6. 如果想减少一些爬虫的调试信息,可以在setting.py中巴log_level调高,默认是DEBUG,改成INFO,或者WARNING可以减少很多不必要的信息,但这是在你确保爬虫没问题之后才能做的。
  7. 自己写的pipeline一定要在setting.py中添加进去,否则是无效的。
  8. DropItem是一个异常调用,应该写raise DropItem(‘your info’),而不是把它当一个普通函数来调用,那样是无效的。
  9. 爬虫要爬哪些URL,这个是不需要担心会重复的,scrapy自己的调度系统里面有基本的duplicate filter,但是获取的item是否有重复,就需要你自己在pipeline里面判断了。因为url不用担心重复,所以你在枚举下一级的链接时,可以放心大胆的yield大量页面链接,我刚开始担心有重复,每次只yield下一页的链接给parser,结果速度非常慢。
  10. 不要爬墙外的网站,除非你有绝对稳定的翻墙途径,否则在爬了一大半之后看到一堆twisted io error然后爬虫挂掉,真是很痛苦的事情。最好直接把爬虫放在国外服务器上爬被墙的网站,事实证明国外的VPS比国内最快的翻墙路线执行爬虫的速度还要快三倍。
  11. Concurrent Connection Per IP/Domain可以调大,16线程是小意思,默认的8线程太慢了。
  12. 这个异常可以用来手动关闭爬虫,记住,和DropItem一样,这是个异常,要raise而不是调用。
  13. 使用selector匹配网页内容时,要多挑写页面测试xpath规则,因为某些元素在第一页存在,在后面的页面中就不一定存在了,这样xpath extract出来的可能是个None,这个时候你还用原有的规则取第一个元素,就可能爆IndexError Exception,直接让程序停掉。
  14. 任何Exception都可以让爬虫停掉,所以一定要多做抽样测试,免得跑了一半挂掉,再改程序重跑。我建议的检查顺序是,先关闭pipeline,也不做具体内容抽取,只先做链接抽取,这样让爬虫跑一段看看Console的输出信息,先确定自己要抓的各种链接都有被覆盖。然后就是抽一部分页面做具体内容抓取,确保你用的xpath规则能覆盖所有页面而不报错,如果单纯的xpath规则不行,你要考虑xpath+re正则表达式,后者的鲁棒性要好很多。
  15. 对于ajax内容,要分析网页,找出最终的数据来源。因为ajax的本质就是javascript在你本地的浏览器执行,偷偷的又向服务器查询了一次数据用于填充页面,你只要找出这个偷偷查询的内容,然后用requests之类的模块查询一次就可以了。
  16. 对于普通的link,scrapy本身会检查并确保页面被成功抓取(在网络没断的前提下),基本不用担心数据完整性。对于ajax内容你用其他方式查询了数据的,需要处理好查询方法的返回值,在没有查询成功的情况下,可以让pipeline有个标志位来判断是否需要重新抓取,还是把这些不完整的数据存到另一个数据库以后再修补。
  17. 在匹配xpath规则时,如果你在firebug中调试,请一定先用Noscript之类的插件禁用脚本。因为有些网站在启用js和不用js的情况下,很多元素的class名字是不一样的,而爬虫看到的页面永远是没有js脚本执行的,最简单的方法还是先用scrapy shell抓一个页面,测试好xpath规则之后再写代码。
  18. 对于日文页面,标准的‘GBK’编码可能不足以显示所有字符,可以用str.encode(‘GB18030’)的方式先扩到GB18030编码,这个编码基本是可以覆盖CJK所有字符的。
  19. 对于matplotlib中,生成图片里中文的乱码,加上下面这样一行,给中文指定个中文字体就好了。
     
  20. 当数据量大的时候,保存数据用jsonlines而不是json,这样就算有个别数据因为网络或文件io问题不完整的时候,顶多损失一行数据,而不需要再一个几十万字节长的单行里查找哪里错了。
0 0
原创粉丝点击