Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4584620
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Python/Ruby

2014-12-27 12:23:26

原文地址:http://blog.raphaelzhang.com/2013/11/grab-web-data-go-vs-python/

这几天要帮老婆下载几个上的数据,正好在试用Go和Python,便用了Python和Go写了两个程序来抓取数据。当然,分析数据这种高难度的事是搜索引擎帮忙搞定的,具体说是这篇文章给出了好全的一个视频抓取分析。

用Go写的代码大概在160行左右,Python的大概在110行左右,可以发现比起Python来说Go的代码还是更长一些,而且Python的代码也很易懂,因此如果是后台的脚本程序,还真是用Python更好一些。

其中差别最大的大概就是抓取数据的代码了,下面是Python的:



下面是Go的:



使用Go代码较长的原因一个是Go没有异常,所以中间会有很多err的忽略和处理,而Python直接用一个大的try/except搞定了,另外一个是urlopen方法有一个timeout参数,而Go没有相应的参数,因此需要自己通过channel来实现,这个也会导致代码比较长。

另外Go还有一个稍微不习惯的地方,python里面列表切片不用管是否超出了边界,例如有一个列表a,即使长度是3,我也可以通过a[:6]来访问a的前六个元素,不用事先判断,这样代码会比较简洁,Go需要先判断len(a)是否至少是6,然后再a[:6],不然会出错。

当然,代码短不一定都好,例如Python和Go分析下载URL的代码,虽然Python的代码较短,但是从维护性和性能来说,还是Go的更好。下面是Python的:



而Go由于有goroutine和channel,就非常优雅,如下:



从上面的代码看来,主要是Go解析json数据需要自己先定义几个struct type,但是你可以忽略自己不感兴趣的字段,其实也十分棒的,我觉得这些多出来的代码还是不错的。

总体来说,Go和Python的易读性都不错,而Go在Web数据抓取上缺乏不少方便的模块和参数,模块例如没有lxml,因此解析真实的html比较麻烦,而参数例如上面说到的timeout参数,还有一个就是Go没有内建的字符串编码解码模块,这个太不方便了,完全应该是内建模块才行。用Linux改的iconv什么的在Windows上编译真是麻烦死,我个人是很讨厌mingw和cygwin这种东西的,几年前在正式工作中折腾了这些玩意半年,别扭极了,例如cygwin的下载和配置就很麻烦,还有各种路径和编码的问题。

Python用惯了,一些小语法糖在Go里面没有感觉有点不习惯,例如列表推导,还有例如’+’*80打印重复字符,不过这些都是细节了 :)

当然,Go的goroutine和channel实在是很强大的,另外Go运行时环境要求简单太多了,因此我完全可以直接把Go编译出来的程序复制给其他人用,不像Python,还需要装一个Python环境(有时候还要装一堆第三方模块,例如lxml/PIL之类的),真是折腾啊,因此Python也只适合后台脚本。

下面是Python与Go抓取搜狐视频的完整代码,不过这些视频网站变得非常快的,也许过几个月就不能用了,主要是留在这里做个对比而已。

另外需要注意的是Go里面getDownloadUrls的实现假设的是最多只有一个模板会匹配下载视频,而且原始网页中必须要有vid这个js变量的声明,其实在搜狐视频里并不完全是这样的。有的时候会同时匹配两个模板,有的时候会声明vids变量。前者需要修改getDownloadUrls与getDownloadUrl函数,不要在getDownloadUrl里面close(dataCh),而是在getDownloadUrls里defer close(urlCh),然后再在getDownloadUrl里面return之前(包括最后的隐式return)向dataCh发送一个长度为零的字符串,在urlCh接收到长度为零的字符串以后就知道有一个goroutine处理完毕了。

这里是Python的。



下面是Go的:



2013.11.24的补充:

Python抓取Web网页用也是很方便的,但是对我而言,requests的大部分功能也没啥用,urllib2与cookielib大部分时候已经足够使了,而到处安装第三方模块也是非常麻烦的,所以也就很少用requests了。还有一个就是原来python里面检测字符串编码的chardet模块已经没有了,但是现在又有了一个,这个用来做编码检测也是不错的。

阅读(2599) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~