设计爬⾍Hawk背后的故事正则匹配快代理
本⽂写于圣诞节北京下午慵懒的午后。本⽂偏技术向,不过应该⼤部分⼈能看懂。
五年之痒
2016年,能记⼊个⼈年终总结的事情没⼏件,其中⼀个便是开源了Hawk。我花不少时间优化和推⼴它,得到的评价还算⽐较正⾯,因为负⾯评价也没什么渠道进我⽿朵。
不过你知道我写这个东西花了多久吗?掐头去尾,这是第五个年头了。
读研究⽣伊始,实验室开始做数据挖掘,但我发现⼤家做研究,都是⼀段段的代码,遇到新问题,就不得不再拷贝⼀份修改,很少想过复⽤。于是我便花了⼀年的时间,开发了⼀款现在看起来配⾊丧⼼病狂的“数据挖掘软件”:
它居然能在上⾯刷微博,能把任何⼀个学学妹在微博的蛛丝马迹全扒出来,渲染出配⾊更丧病的绚丽图表(这⾥有更详细的细节)。实验室⽼师最喜欢拿这套软件给参观的领导演⽰了。
我多少有点偏执,想⽤纯图形化的⽅式构建数据挖掘的全部流程:从获取清洗数据,建模,训练到最后可视化。但以我当时的算法和软件⽔平,这样的东西根本就不可能做完善,我还意淫着能把它商业化。最终结果,是它跟着我⼀起毕业,除了我和⼏个学弟之外,没⼈⽤过。
⼯作后,靠业余时间维护它有很⼤的困难。数不清的bug和时间花销,让它成了拖后腿的包袱。⼀些考虑不周的接⼝,设计于⼏年之前,后来想修改却花费巨⼤。更重要的是,它的未来在哪⾥?
时值2015年,桌⾯软件已死,web都已过时,移动端才是兵家必争之地。这种⼤杂烩和复杂度,普通⼈不可能会⽤,程序员没有⽂档不爱⽤,⼤神不屑于⽤。
我也不想让它扔在历史的故纸堆⾥⽆⼈问津,索性就开源吧!
在开源之前,我做了⼀件事,将它改名为Hawk,寓意为驰骋天空的鹰;把我⾃⼰⽤的次数少于10次的组件全部删掉,连3D可视化,统计和预测模块也不幸免:只保留爬⾍和数据清洗,因为分析和挖掘已经有其他⼯具做得更好了,⽐如Python那⽆⽐强⼤的⼯具链。我认识到,只做⼀件事,并将其做好是多么重要。
⽼司机送它上路了,那⼀天,它正式出现在GitHub上。
我对Hawk的评价
我就是⽤程序员的思路去设计Hawk的,好玩有趣是最重要的。
先说优点:起码它能⽤,⼏乎没接触过编程的⼈,也能在看过教程后,做出他⾃⼰的设计,熟练后效率会很⾼。
我最喜欢的是⼿⽓不错,升级Hawk2.0之后,绝⼤多数⽹页都可以通过⼀键提取数据。其实原理很简单,就是树结构的模板匹配。
其次便是那个所见即所得的数据清洗,在调试模式下快速设计任务,在执⾏模式下并⾏执⾏。恕我孤陋寡闻,这种基于流式管线思路,在其他软件上⽤的并不多。
最后便是⼦任务,再复杂的需求,都可以通过⼦任务分⽽治之,⽐如多次定向跳转。这东西让⼋⽖鱼和⽕车头去试试看?
Hawk最⼤的价值,是将复杂的逻辑链条化和可视化了,你可以将代码变得不那么耦合,像搭积⽊⼀样⽅便地组合。当然这些都拜于函数式编程的思想所赐。
再说缺点:Hawk有很多的bug,没单元测试,功能不完善。但这都不是最根本的缺点,最根本是难于实现条件判断和循环,你很难写出
if,switch和while。这也是函数式语⾔的共同问题,你不得不逼迫⾃⼰⽤另外的思路去解决。虽然通过引⼊⼦任务,能“不够优雅”地解决它,但依旧要花费不少脑筋。
有的⼈觉得Hawk不够强,这是因为它是图形化软件。为什么具备UI的软件很难和命令⾏相⽐?因为设计UI的新功能时,不仅需要考虑它的算法,更要考虑它如何在UI上呈现。有些功能⾮常有⽤,⽐如爬⾍常见的BFS和DFS(深度和⼴度优先遍历),但在UI上配置会异常繁琐,我不得不将它们抛弃掉,只保留最常⽤的功能。
为什么呢?轻松写BFS的⼈,会想⽤Hawk吗?应该不会,他们也许会直接敲代码。
Python版本的Hawk: etlpy
因为图形界⾯和C#本⾝的诸多不⾜,我开始发展了Python的Hawk,称为etlpy (Extract-Transform-Load in Python)
最初的想法,是将Hawk⽣成的配置⽂件(xml)交给etlpy去执⾏,初看很酷,但这种思路被证明不靠谱,两种语⾔,使⽤不同类库,对同⼀个任务流,就因为在底层的细微偏差,会导致结果的完全不同。我花了⼤量的时间在解决兼容性问题上,发现难度不⼩,两者互相制约牵绊。
最终,我放弃了所谓的兼容性,之后etlpy功能⽇新⽉异,甩了Hawk有10条街不⽌。Hawk的5分钟拖拽,在etlpy上只要⼀句话:
url='wwwblogs/p{0}'
t=task().let('p').range('1:20').format(url).detect().let('dignum').split('_')[0].num().write('cnblogs.json')
介绍etlpy的语法超过了本⽂的范畴,但它拥有Hawk的⼀切优点,同时能够分布式并⾏抓取,任务队列,超级代理,定时更新,与任意函数库集成。执⾏引擎(etlpy)的全部源代码,也就1000⾏出头。
也许你都没有听过Lisp这门语⾔,不过没有关系:Hawk是⽤C#写的,⼿敲的代码⼤概有1万⾏,⽤Python⼤概是1000⾏左右,⽤Lisp只要300⾏就能实现它的全部功能!当然,没有图形界⾯。由此可见编程语⾔在表现⼒上的巨⼤差别。Hawk本质上是个可视化的Lisp设计器。
我喜欢语⾔的纯粹和精妙,⽤简洁的语法就能代表复杂的逻辑。Hawk其实定义了⼀种爬⾍语⾔,对诸多常⽤操作进⾏了模块抽象,在拖拖拽拽中,你构建了⼀张图(Graph),数据在图上流动,被⽣成,清洗和消费。最近⼤热的Tensorflow不也是⼀样的思路吗?这张图,既是数据,也是代码。
当然,不论是Hawk和etlpy,你都不能把它们当成厨⼦,给它指令,就能做出⼀道菜来。⽽应当成⼀套顺⼿的厨具,⽽真正做菜的那个⼈还是你。⾃动化只是解决了部分问题,⽽巧妙设计的源泉还是来⾃于操作者本⼈。最强⼤的⼯具,是⾃⼰。
我们⽤语⾔表达概念,模式和流程,在此之上构建抽象。我假定每个⽤Hawk的⼈都能触类旁通,因此通过⼀些通⽤的介绍,他应该就能理解绝⼤多数的功能。那如果还是不懂呢?那不好意思,请⽤⼋⽖鱼,否则Hawk的很多设计,对他来说
就变得没有意义。我⾃⼰从来不愿意把Hawk和etlpy定义为爬⾍,它们提供的是⼀组环境,语⾔和⼯具,爬⾍只是它的⼀个不错的应⽤场景⽽已。
为什么要开源?
有⼈肯定会问,为什么不把Hawk商业化,去赚⼀笔钱呢?
理想状态下,成⽴公司去完善推⼴和销售软件,那么应该⾏得通,否则单匹马是不可能的。那我是不是值得为这套软件成⽴公司呢?应该不会,因为它只是个⼯具,还不值得我去开⼀家公司去完善它。
我相信,这也是很多程序员⾯临的类似困境,想靠卖软件盈利,就像路上的煎饼摊⼀样简单朴素,问题是放在10年前还有可能(记不记得30元⼀套的⾦⼭词霸?)⽽服务化盛⾏的今天,可能很低。到处推⼴,最终只可能沦为某天我在咖啡厅⾥的⼏句谈资,不可能有什么⼤⽓候。
有朋友说,为什么你要开源,对⾃⼰来说是不是有点像代码外泄?⾕歌的TensorFlow都开源了。前⾯的路还有很远,⼤家都要忙着赶路呢。保护代码最好的⽅式就是开源,没开源时有⼈还想着破解研究,开源了⼤家fork⼀下然后就没有然后了,“得不到的才是最好的”。
不得不说,开源才是最贵的。⼤家看到开源,欢欣雀跃,以为在路上捡到了钱,其实不是的,如果你真想⽤起来,⼀定会花更多的时间来学习它,因为开源者没有义务像商业软件那样,提供完整的⽀持。时间和钱总是⽭盾的,既想省钱还
想省时间,天下没有这样的好事。
我以前天真地以为,开源的全部就是把源代码公开在⽹上。之后难道不是理所应当的声望,⼀帮⽜⼈帮你优化功能修复bug吗?
哈哈,开源怎么可能那么简单。
如果软件写得不错,但没有宣传,那挂在⽹上完全⽆⼈问津,没⼈知道那是什么⿁;写得⾜够好,宣传也到位,那也很难有⼈帮忙贡献开发:往上看,⼤神们都忙着造轮⼦;往下看⼀⼤帮实⽤主义者,抄起轮⼦就上路,谁顾得上看轮⼦是不是圆的呢?
开源不意味着坐视不管,依旧需要⼤量的精⼒去培养完善它和它的社区环境,通过邮件和论坛⽅式提供⼀定的服务。这件事情如果不⽤⼼,
则⼀事⽆成。
如果pandas和ipython不开源,我现在也可能⽆法进⼊数据分析的殿堂,没有Linux和众多开源⼯具,世界也不会发展成这个样⼦。我明⽩了为什么开源是⼀种哲学,它是⼀种“共赢”。对程序员来说,名誉和成长⽐卖软件带来的价值更⼤,那是认可感和成就感。对其他⼈来说,开源带来了时间的节省和实际的财富。这样做必然是有价值的。
你肯定会问,那为什么etlpy后来不更新了?
第⼀它不稳定,现在释放出来可能砸招牌。其次,如果释放出etlpy,能量和Hawk完全不是⼀个数量级,它可能会让⽹站变本加厉地防爬⾍。请理性使⽤爬⾍
开发完Hawk的那段时间,我也和很多⼈⼀样,看到⼀个⽹站就想去试试。以我的熟练程度,20分钟数据就都被下载下来了。然⽽数据保存在硬盘上,⼏乎不产⽣价值。
Google的⼯程师,可以下载它的全部源代码。可是为什么没有另外⼀家Google,甚⾄另外⼀家百度(⼜⿊了百度)出现呢? 因为更重要的是⼈才,资源和商业模式,代码在这件事情中最不重要了。拿到源代码都没⽤,更遑论挂在⽹上供⼤众阅读的数据呢?
爬⾍是灰⾊区域,所以⼤公司从来不公布任何爬⾍框架,但内部⽤的⽐谁都多。两年以来,⽹络发⽣了巨⼤的变化,ajax化,SEO变成了关键词⼴告位,⼤量的⽹站开始强硬地反爬⾍,之前能随便抓取的⽹站,现在都变得很困难。我相信这⾥有相当⼀部分是Hawk的功劳。让⼈郁闷的是,不少⼈抓数据仅仅⽤来玩。
可以想象,⼀⼩部分标榜⼤数据和AI的公司,把Hawk的代码弄下来改改,添⼀点数据报表功能,就可以盗⾛别⼈⽹站数据,⾃⽴门户,去到处忽悠。虽然Hawk开源协议是GPL(使⽤开源代码的必须开源),但这完全限制不了,毕竟是中国嘛。可能他们不知道,数据,⼯具和算法根本不值钱,理解,洞见和执⾏才是最重要的,可是这部分却需要真⼑真的本事。
总之,稍微理性⼀些,适可⽽⽌吧。
为什么不继续优化?
很简单,因为没有时间。爬⾍本⾝没太多技术含量,再深⼊就进⼊了异构Web数据集成的领域,⼤部分⼈根本⽤不到。这是个拥有数不清trick和dirty技巧的领域,是与⽹站设计者的攻防战争,玩到最后,你的能⼒曲线就像log函数⼀样,被压制在⼀个确定的上界。
现在是⼈⼯智能和深度学习的天下,以我所在的团队为例,⾝边的⼤神们都在努⼒地优化Tensorflow,改造算法的底层来提升效率,在有趣的数据集上做⼤规模并⾏训练。
⼏年之前,如果我没有去做爬⾍和Hawk,没有去设计正则解析器tnpy,⽽是紧跟潮流去做⼤规模机器学习的话,眼界和⾝价可能就完全不⼀样了呢?
当然,我不后悔去做Hawk,它是实实在在的能让⼤众⽤起来东西。或许在万⾥之外,有个⼀样戴着眼镜充满激情的和我⼀样的nerd,看到我的代码开⼼地拍了桌⼦,⼤喊“f**king nice work!”到那个时候,其他事情还重要么?
如果说我后悔没做什么,是我没有把软件做成英⽂,曾经有⼀段时间我个⼈⾮常崇尚中⽂编程,从⽽酿成了现在软件国际化异常困难的后果;再者,没有直接开发Python或者js这种能跨平台语⾔的版本,Hawk只能局限于Windows桌⾯应⽤,⽽不同的社就风⽓⼜不⼀样了。
它的设计有不少问题,不过更多来⾃于多种因素的妥协。它注定是不完美的。因为职业⽣涯的关系,我⽆法像前⼏年那
样,花⼤把的时间去优化它。既然开源了,我希望有⼈能把它做得更好。
其实还是个程序员
我之前从来没想过⾃⼰会成为⼀名程序员。
⾼中时候理科不错,语⽂巨差。⾼考完,⽼妈扯着嗓⼦问我,报哪所学校什么专业吧?正在打游戏的我根本⽆暇顾及,不耐烦地说,随便你们吧!糊⾥糊涂地进了通信⼯程,⼏年后通信稍显疲软,就⾃学计算机,然后⼀点都不偶然地成了⼀名程序员。
⽹上⿊程序员的段⼦太多了。我都⼀笑⽽过。但最近⼏年我坚决不买任何尺⼨和颜⾊的格⼦衫。如果看到我穿,好吧,那⼀定是我本科时候买的。
你知道那帮每天不苟⾔笑,整天盯着显⽰屏的怪⼈每天在想什么吗?
也许看“”能稍微解决⼀下这个问题吧。不过,敲完这些⽂字的时候,九点半我还在杭州的酒店⾥睡眼惺忪,谁让昨天夜⾥11点才回来的呢?
总之,欢迎使⽤Hawk,欢迎和我交流有关它的各种问题和建议。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论