--
前阵子把之前在博客上写的所有关于爬虫的文章都搬到了简书,这导致我在简书的文章总字数直接突破了10W,接着一个残酷的出现了:在这之后的很大一段时间内,我的阅读喜欢评论关注的数量,为零。
在15年的时候,我写了一篇《当我选择出国时我做了什么》,该文迄今为止被阅读6164次,收获评论49,喜欢491。这一落差说实话还是受了点打击的,好在渐渐地,爬虫文章也收到了一些喜欢(共553个喜欢有491个来自于3年前的一篇文章),粉丝也涨到了62,虽然评论仍然寥寥无几,不过好歹也算是一种进步(惭愧)。在这里,给这62位朋友送上我的谢意,感谢你们对我认可。
上个月初,我入职了一家公司,正式开启了我的爬虫职业生涯。虽然之前自学或者说自己钻研并编写了很多爬虫,不过当我第一次见到一个完成的爬虫系统的时候,坦白说,还是觉得挺不可思议的,我大概花了2到3个礼拜对这个系统进行了熟悉,现在在保持对原系统的进行维护的同时,正着手对其进行性能优化。随着理解的深入,我越发觉得爬虫工程师的瓶颈其实并不是JS、css之类的前端反混淆技术,也不是requests、BeautifulSoup之类的网页获取解析技术,当然也不是仅仅对爬虫框架的使用。这些技术固然是必须的,但是真正的上升瓶颈还是工程师的素养:如何写出一个高性能可扩展的爬虫系统?系统如何兼容数百个甚至数千个不同类型的爬取对象(网站)?如何管理这些爬虫?如何高效的并发这些爬虫?如何处理爬取之后的数据?各个子系统之间如何交流?和这些问题比起来,对某个特定网站的爬取的问题只能算是个入门级问题。
再过两个礼拜我就要举行婚礼了,结婚的事情前前后后准备了差不多大半年,最近两个月都在一件一件落实之前计划的东西,因此周末基本没时间写博客了,毕竟技术博客不是拿起电脑就能写的,需要一个准备的过程。另外,因为刚入职,压力也比较大,平时的时间都花在了熟悉业务上,希望能够早日接手项目,说起来,入职刚满一个月,我又新学了两门语言:ts和lua,之后也会说说这两门语言。说起来来上海这一个多月,本周末是我唯一一次在上海度过的周末,也算是难得有时间,更一下博客。总之,下个月开始,婚礼也办完了,业务应该也熟悉的差不多了,相信也能找到工作生活的平衡点,以后会定期更新博客。
我未来一年的主题词是学习,疯狂学习。我需要一定的时间将我在国内断档的三年补上,同样也需要一定的时间将国外学到的东西进行转化、推演、应用在个人的发展中,根本目的还是提升收入水平。
关于博客的话,在作为记录平时的所见所闻所思所想的工具,或者作为同道中人结交的敲门砖的同时,如果能产生一些经济效益,自然是最好了。事实上,我希望这部分的效益能够占据我收入中很可观的一部分,因为写文章是为数不多的能让我感受到简单的快乐的事情之一。最近我也在读关于自媒体运营方面的书籍,也和公司的编辑和运营进行了一定的交流,我的性格是谋定后动,因此这点上我也需要点时间琢磨一下。关于博客内容应该会很快决定下来。
另一个我认为很重要的想法是我想为我的爬虫职业生涯定一个目标,这个目标的实现将作为爬虫生涯的一个重要的里程碑。我初步的想法是编写一个研究型的通用爬虫框架,将其开源。这其实是一个很宽泛的概念,就框架而言,以我这个月粗浅的认知,我觉得是完全可行的,只是需要一定的时间而已(不会短)。为什么称其为研究型呢?我希望能将整个开发过程记录下来,每一次迭代,每一次修补,每一份文档,事无巨细,全部记录下来。这样如果有人想成为一名爬虫工程师,顺着这条路再走一遍就行了;另一方面,我希望这个项目能够做到“核心模块可拆卸”,这样任何对这个项目熟悉的人就可以以这个项目为基础进行二次开发,替换合适的部分来处理具体的业务需求(或者完成一定的研究任务?)。我相信任何人如果能融汇贯通这个项目,称自己一声合格的爬虫工程师绝对一点不过分。这方面如果有朋友有兴趣,可以联系我。如果最终能做成scrapy这种级别的开源项目,我做梦都会笑醒的。
还有一个小目标就是我希望我能继续保持刷题的习惯。大概就是这样。
我之前写了很多关于爬虫的文章,涉及了各种各样的爬取策略;也爬了不少主流非主流的网站。从我刚入门爬虫到现在,每一个爬虫对应的文章都可以在我的博客上找到,不论是最最简单的抓取,还是scrapy的使用。
然而爬了这么多网站,按理说应付一位爬虫工程师的工作应该绰绰有余吧?当然不是,正如我上文所说,在整个爬虫系统中,如何抓取某个特定的网站其实是最小的任务模块。而对于一个有爬虫需求的公司而言,一个能够长期稳定运行的爬虫系统才是基本需求。
我从另外一个角度解释一下这个问题,如果我们将“爬取某个页面”称为一个爬虫任务。那么一般而言,我们会需要定期执行这个爬虫任务以满足业务上的需求。比如说,我这有一个爬虫任务是“爬取某只股票的当前价格”,那么我可能会要求每10s执行一次这个爬虫任务以达到汇至股价走势的目的。问题就来了,爬虫系统如何保证每10s执行这个爬虫任务呢?time.sleep(10)? crontab?open_signal?send_task?
最简单的,你可以让程序执行一次爬虫任务后sleep10秒,然后无限重复这个循环。嗯,如果只有一个任务,理论上是可行的,此时这个程序就是一种爬虫系统。那么比这种解决方案略微高端一点的就是写一个定时任务,每10秒执行一下,这下连爬虫系统都省了。
但是如果这种爬虫任务有很多呢?比如说,我要绘制1000个不同股票的股价走势图。简单一点的可以将爬虫任务改成可接受参数式的,每10s中传入1000个参数(股票代码)并用多进程或异步执行这些任务。用scrapy也可以解决这个问题,scrapy其实非常适合这个场景,但是scrapy没有定时任务,这个时候可能又会需要用到scrapyd和celery。接着,如果有100W个爬虫任务呢?虽然有些爬虫只需要简单调整一下参数,这些任务可以当成同一类爬虫,但即使去除这些同类型爬虫,仍然会剩下不同类型的爬虫任务,比如说30W?那么这30W个任务我们怎么处理,不可能在一个scrapy里写30W个spider?然后还会涉及到调度,因为每个爬虫的抓取频率可能是不一样的;管理,爬虫任务可能会根据产品需求出现增删的情况;爬取结果处理,比如说去重(对100W个结果去重本身也是个不小的事情)、存储等等。
另外,一个健康的爬虫生态,一般还需要一个代理池,一个网页渲染服务器,像爬微博的话可能还需要Cookie池,然后这个系统本身应该是高可用高可扩展的。随着爬虫任务数量的增加,各个地方都有可能产生性能瓶颈。这也是我为什么说,爬取任务其实是最小的一环,对于单次任务的执行速度,甚至有时候它的成败都不是关键。
插一句,scrapy仍然是一个很强大很厉害的框架,它是我目前认知里最牛逼的爬虫框架。它的厉害不在于它可以方便的编写一个爬虫,而是它的模块定制功能,你可以根据实际的产品需求,通过调整中间件或者调度器方便的实现你想要的功能。
但是有时候偶尔会出现一些反爬特别厉害的网站,这个时候就需要对其进行单独的研究了。另外,我以为手机端抓取其实是一个很关键的手段,现在的手机性能强大,能做的事情实在是太多了,只是大多数时候被人忽略了。个人以为这可能会变成今后一个主流的抓取手段。今后我也会开始学习这方面的知识。