本文主要介绍爬虫系统的架构,具体的爬取细节和所使用的语言都可以自由选择。
以下是我从网上截取的一位前辈提炼的,对于爬虫系统的要求,我觉得很有道理。
我的设计尽量依据以上七条原则。
首先我觉得一个完整爬虫系统应该包括三个子系统:页面爬取系统,内容入库系统,内容管理系统。
三个系统之间必须低耦合,以实现分布式和可伸缩性的要求。
页面爬取系统负责从第三方页面抓取内容,并提交到内容入库系统的原始数据队列中。
内容入库系统会维护一个原始数据队列,实现一些去重以及基本的内容有效性判断,经过审核后的数据才可以进入数据库中。
内容管理系统主要提供一个管理后台,针对数据库内的内容进行人工的审核和编辑。
使用者三个系统的分工合作,可以基本实现以上的一些硬性需求。相应的也需要两到三种类型的服务器,爬虫服务器/数据服务器/运维服务器。对于数据量要求并不高的情况,这三种服务器可以重叠成同一台服务器。爬虫服务器用来部署页面爬取系统,数据服务器用来部署内容入库系统以及数据库,运维服务器主要用来部署内容管理系统。一旦数据量比较大的情况下,压力会比较大的可能就是数据服务器了。之所以将数据库和内容入库系统划分到了一类服务器里面,主要是因为两者之间的操作过于频繁,在同一台服务器上会避免带宽带来的限制。
下面分析一些具体的实现方案。
队列的实现,整套系统中会有好几个队列,相应的都会有其自身队列的管理机制,不论其具体逻辑是什么,使用的技术都推荐使用redis数据库来做。访问速度快,较大数据量处理方便灵活。
页面爬取系统,主要是根据自身需求对于各个目标网站进行爬取,每个不同的目标网站可能有不同的更新周期,所以爬取的循环周期也要相应的注意,尽量避免不必要的服务器开销。所以爬取系统也需要维护一个任务列表,按照惯例任务列表使用redis来实现队列,而且需要对单个任务的爬取周期要有定制要求。有任务列表就需要有一套任务发布和删除的程序来向列表中插入和删除数据,还要有一套执行任务的程序来执行爬取。执行之前需要先判断当前是否处于该任务的爬取周期内,如果在就执行爬取,否则跳过(注意:任务执行完成后不会从队列中移除,任务的发布和移除操作都只在任务发布移除程序中做)。任务列表是被循环执行的,也就是每次执行到末尾任务后,又重新从头部任务开始重新遍历。爬取系统很多人都喜欢使用python语言来做,python做爬虫代码相当精简,也有一些比较不错的框架,我一般是用django结合一些其他的插件感觉够用。
内容入库系统,首先是原始数据队列,用来接收来自页面爬取系统的数据,按照惯例原始数据队列使用redis来实现队列,原始数据队列是一个“阅后即焚”的队列,一旦该条数据被入库程序处理过了,就将该数据从队列中移除。入库程序使用python的django框架,对于数据库操作无与伦比的便利。数据库使用mysql。
内容管理系统,虽然看起来像是一个比较鸡肋的环节,但其实他的存在直接决定了整个项目的进展,因为这一步是与人工打交道的部分,通常来说,人工部分总是效率最低的部分。如果不能提供高效的工具,会直接拖慢系统进展。内容管理系统的开发使用什么建站语言(php/python/java等等)都可以,因为在这一步,数据库已经成型,所需要做的只是通用的数据读取部分。