基于Hadoop 的分布式网络爬虫技术学习笔记
一、网络爬虫原理
Web网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据来源。很多大型的网络搜索引擎系统都被称为基于 Web数据采集的搜索引擎系统,比如 Google、Baidu。由此可见 Web 网络爬虫系统在搜索引擎中的重要性。网页中除了包含供用户阅读的文字信息外,还包含一些超链接信息。Web网络爬虫系统正是通过网页中的超连接信息不断获得网络上的其它网页。正是因为这种采集过程像一个爬虫或者蜘蛛在网络上漫游,所以它才被称为网络爬虫系统或者网络蜘蛛系统,在英文中称为 Spider或者Crawler。
二、网络爬虫系统的工作原理
Web网络爬虫系统一般会选择一些比较重要的、出度(网页中链出超链接数)较大的网站的URL作为种子URL集合。网络爬虫系统以这些种子集合作为初始URL,开始数据的抓取。因为网页中含有链接信息,通过已有网页的 URL会得到一些新的 URL,可以把网页之间的指向结构视为一个森林,每个种子URL对应的网页是森林中的一棵树的根节点。这样,Web网络爬虫系统就可以根据广度优先算法或者深度优先算法遍历所有的网页。由于深度优先搜索算法可能会使爬虫系统陷入一个网站内部,不利于搜索比较靠近网站首页的网页信息,因此一般采用广度优先搜索算法采集网页。Web网络爬虫系统首先将种子URL放入下载队列,然后简单地从队首取出一个URL下载其对应的网页。得到网页的内容将其存储后,再经过解析网页中的链接信息可以得到一些新的URL,将这些URL加入下载队列。然后再取出一个URL,对其对应的网页进行下载,然后再解析,如此反复进行,知道遍历了整个网络或者满足某种条件后才会停止下来。
抓取策略:
在爬虫系统中,待抓取URL队列是很重要的一部分。待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪个页面。而决定这些URL排列顺序的方法,叫做抓取策略。下面重点介绍几种常见的抓取策略:1.深度优先遍历策略 深度优先遍历策略是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接。我们以下面的图为例:遍历的路径:A-F-G E-H-I B C D2.宽度优先遍历策略宽度优先遍历策略的基本思路是,将新下载网页中发现的链接直接插入待抓取URL队列的末尾。也就是指网络爬虫会先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此网页中链接的所有网页。还是以上面的图为例:遍历路径:A-B-C-D-E-F G H I3.反向链接数策略 反向链接数是指一个网页被其他网页链接指向的数量。反向链接数表示的是一个网页的内容受到其他人的推荐的程度。因此,很多时候搜索引擎的抓取系统会使用这个指标来评价网页的重要程度,从而决定不同网页的抓取先后顺序。 在真实的网络环境中,由于广告链接、作弊链接的存在,反向链接数不能完全等他我那个也的重要程度。因此,搜索引擎往往考虑一些可靠的反向链接数。4.Partial PageRank策略 Partial PageRank算法借鉴了PageRank算法的思想:对于已经下载的网页,连同待抓取URL队列中的URL,形成网页集合,计算每个页面的PageRank值,计算完之后,将待抓取URL队列中的URL按照PageRank值的大小排列,并按照该顺序抓取页面。 如果每次抓取一个页面,就重新计算PageRank值,一种折中方案是:每抓取K个页面后,重新计算一次PageRank值。但是这种情况还会有一个问题:对于已经下载下来的页面中分析出的链接,也就是我们之前提到的未知网页那一部分,暂时是没有PageRank值的。为了解决这个问题,会给这些页面一个临时的PageRank值:将这个网页所有入链传递进来的PageRank值进行汇总,这样就形成了该未知页面的PageRank值,从而参与排序。下面举例说明:5.OPIC策略策略 该算法实际上也是对页面进行一个重要性打分。在算法开始前,给所有页面一个相同的初始现金(cash)。当下载了某个页面P之后,将P的现金分摊给所有从P中分析出的链接,并且将P的现金清空。对于待抓取URL队列中的所有页面按照现金数进行排序。6.大站优先策略 对于待抓取URL队列中的所有网页,根据所属的网站进行分类。对于待下载页面数多的网站,优先下载。这个策略也因此叫做大站优先策略。
三、网络爬虫系统的基本结构
通过上面 Web网络爬虫系统基本原理的介绍,我们可以将一般的爬虫系统基本结构分为 6个模块,这6个模块组成的爬虫系统基本结构图:
(1)配置模块:该模块允许用户通过配置文件来配置爬虫系统。比如,爬虫系统下载网页的深度(层数)、多线程抓取时的线程数、抓取同一网站两个网页的间隔时间和限制待抓取 URL 的正则表达式等等。
(2)已访问URL识别模块:由于一个网页的URL可能会被多次解析出来,所以为了防止同一网页被多次重复下载爬虫必须要有这个模块来过滤掉已抓取的网页。
(3)robots协议模块:当网络爬虫系统第一次对某个网站进行网页采集的时候,要首先抓取robots.txt,然后获知指定不该访问的目录。或者根据会根据网页的Meta信息判断哪些是服务器定义不能索引和访问的,然后只访问能够索引的页面。
(4)网页抓取模块:网页抓取模块主要完成对网页的抓取工作。通过URL建立与服务器的连接,然后获得网页内容。
(5)网页解析模块:从已下载的网页中提取链出链接,然后把这些提取出的URL放入下载队列。
(6)存储网页模块:这个模块的作用是将已经下载网页经过一定的组织存储在本地服务器上或者分布式文件系统中。以备搜索引擎后续模块的处理。
上面这个基本结构是 Web网络爬虫系统必须具备的。在应用时,由于不同的爬虫系统对各个模块的组合方式不同,因此也会形成不同的系统结构。
四、分布式网络爬虫的工作原理
前面描述的是设计一个集中式爬虫系统所必须考虑的两个问题,但是,不论分布式爬虫系统还是集中式爬虫系统都需要考虑这两个核心工作原理与核心基本结构。因为分布式网络爬虫可以看做是多个集中式网络爬虫系统组合而成。结合上面给出的集中爬虫的核心工作原理和核心基本结构,下面本节来阐述分布式网络爬虫的工作原理。
分布式爬虫系统是运行于机器集群之上的,集群中每一个节点都是一个集中式爬虫,其工作原理与集中式爬虫系统的工作原理相同。这些集中式爬虫在分布式爬虫系统中是由一个主节点控制来协同工作的。由于分布式爬虫系统要求多个节点协同工作,这样多个节点需要相互通信来交互信息,所以搭建分布式爬虫系统的关键是网络通信。因为,分布式爬虫系统可以利用多个节点抓取网页,所以,分布式爬虫系统的效率远远高于集中式爬虫系统。
分布式爬虫系统的体系结构有很多种,工作方式和存储方式也很多。但是,典型的分布式爬虫系统都采取主从方式的体系结构。即有一个主节点控制所有从节点执行抓取任务,这个主节点负责分配URL,保证集群中所有节点的负载均衡。另外,关于存储方式,比较流行的是将抓取的网页保存在分布式文件系统上,这样管理多个节点上的数据更加方便。通常情况下使用的分布式文件系统是都是基于Hadoop的HDFS系统。
五、分布式网络爬虫研究现状
目前,最成功的分布式 Web网络爬虫系统主要应用在搜索引擎公司(如:Google)和其他商业性较强的公司里。然而这些公司并没有公布他们分布式爬虫的技术细节并且云计算的应用尚处在萌芽阶段。现在比较著名的分布式网络爬虫有Mercator,UbiCrawler、WebFountain和 Google Crawler。
六、基于 Web数据采集的搜索引擎系统-基本架构
一个完整的“分布式信息获取和检索平台(即基于 Web 数据采集的搜索引擎系统)”可大体上分为5个模块,而每一个模块都对应着Hadoop的一个或者多个 Map/Reduce任务。这5个模块分别是:分布式采集模块(即爬虫)、分布式分析模块、分布式索引模块、分布式检索模块和用户查询模块。
首先,分布式信息获取模块负责抓取网页的工作,这部分由若干个 Map/Reduce过程共同协作完成。抓取下来的网页经过初步的预处理被保存在分布式文件系统(HDFS)中,构成原始文本库。其次,分布式分析模块负责对原始文本库中的网页进行分析,主要是通过文本解析器提供的分词功能来完成的。将分词处理后的结果递交给分布式索引模块,同时分析模块还会对用户提交的查询进行分析。再次,分布式索引模块负责关键词出现频率分析和创建倒排索引。关键词分析之后生成索引词典,索引器创建倒排索引之后构成索引库保存在分布式文件系统(HDFS)中,创建索引这部分也是由若干个 Map/Reduce过程组成。另外,分布式检索模块负责去索引库中查询索引完成检索将结果数据集反馈给用户。最后,用户查询模块负责用户和搜索引擎之间的交互。用户先向分布式检索模块提交查询,检索模块将查询后的结果集合按照某种规则排好序返回给用户。
七、分布式爬虫系统的结构设计
7.1爬虫基本流程设计
下面对爬虫系统的基本流程进行详细的说明:
(1)先将择优选择的URL种子文件集合从本地文件系统上传至 Hadoop 集群分布式文件系统 HDFS的in文件家中,in这个文件夹始终存放当前层要抓取的 URL。同时,设置已抓层数为 0。
(2)判断 in文件夹中待抓取队列是否为空。若是,跳转到(7);否则,执行(3)。
(3)抓取 in文件夹中的待抓取队列。这个抓取过程是由CrawlerDriver模块完成的,该模块是一个基于 Hadoop的 Map/Reduce过程。后面我们将详细介绍CrawlerDriver模块的 Map/Reduce详细实现。最后将抓取下来的网页存放在HDFS的 doc文件夹中。这个 doc文件夹存放着每一层未经加工过的网页。
(4)解析已抓取的网页,从 doc 文件夹中已抓取的网页中提取出链出链接。这个解析过程是由ParserDriver模块完成的,该模块也是一个 Map/Reduce计算过程。具体抽取实现是在 Map阶段通过 HTML解析完成的。后面我们将详细介绍 ParserDriver模块的 Map/Reduce详细实现。这个过程结束后会将抽取出来的链出链接保存在 HDFS上的 out文件夹。这个 out文件夹始终存放当前层解析出来的链出链接。
(5)优化解析出来的链出链接,过滤已抓取的 URL,即从 out文件夹中已解析出来的链出链接 URL里过滤掉已抓过的 URL。这个优化过程时由OptimizerDriver模块完成的,该模块还是一个 Map/Reduce过程。后面我们会详细介绍如何基于 Hadoop完成 OptimizerDriver模块的 Map/Reduce实现。优化后会将过滤优化好的 URL集合保存在 in文件夹中等待下一轮的抓取。
(6)判断已抓层数是否小于 depth。如果小于,“已抓层数”自加 1,返回(2);否则进入(7)。
(7)合并去重,将每层抓取的网页进行合并同时去掉重复抓取的网页。这个工作是由MergeDriver模块完成的,同样,这个模块也是一个基于 Hadoop开发的Map/Reduce过程。后面我们会详细介绍如何基于 Hadoop完成OptimizerDriver模块的 Map/Reduce实现。合并后将结果依然保存在分布式文件系统 HDFS上的doc文件夹中。
(8)对抓取的网页做简单的预处理。即将 html 代码转化为 xml。这个工作是由HtmlToXmlDriver模块完成的,同样,这个模块也是一个基于 Hadoop开发的Map/Reduce过程。将处理好的 xml文件存放在 HDFS的 xml文件夹中。
(9)结束。
从上面这个流程中我们可以看出,整个爬虫系统可以分为 5个部分,每个部分是一个独立的完成对应功能的模块,每个模块对应着一个 Map/Reduce过程。下面介绍下这 5个模块的功能:
(1)CrawlerDriver模块:并行下载待抓取队列,把 in文件夹中的文本文件作为待抓取的 URL种子集合,该文本文件在第一轮抓取时是用户给定的初始种子,从第二轮开始就是上一轮提取出来的链出链接。该模块是基于 Hadoop开发的一个 Map/Reduce过程,Map和 Reduce分别完成了不同的功能,具体下载是在Reduce阶段完成的,并且采用多线程下载,下载部分是采用 Java的网络编程完成的。下载下来的网页保存在 HDFS上的 doc文件夹中。
(2)ParserDriver模块:并行分析已下载网页,提取链出链接。根据 doc文件夹中已下载的网页分析出每一个网页中向外指向的链接即链出链接。该模块同样是基于 Hadoop开发的 Map/Reduce过程,但是只需要一个 Map阶段即可完成目标。在 Map阶段主要工作是利用 HTML解析器解析出链出链接,另外,还通过规则限制链出 URL的类型,防止抽取出的链接链到其他网站上。最后将这些链出链接保存在 HDFS上的 out文件夹中。
(3)OptimizerDriver模块:并行优化链出链接,过滤掉重复链接。根据 out文件夹中已提取的链出链接,进行优化,剩下为抓取的 URL交给下一层处理。由于网站层与层之间链接的关系是一个图的结构,所以该模块的工作可以理解成寻找环路的问题,将构成环路的 URL过滤掉。这个模块也是一个基于Hadoop开发的 Map/Reduce过程。将优化好的 URL存放在 HDFS上的 in文件夹中。
(4)MergeDriver模块:并行合并各层抓取的网页。根据 doc文件夹中每一层抓取的网页,进行合并,去掉层与层之间可能重复的网页。这部分也是一个基于Hadoop开发的 Map/Reduce过程。最后,依然将结果存放在 doc文件夹中。
(5)HtmlToXMLDriver模块:并行地将 HTML转化为 XML。根据 doc文件夹中抓取的网页,进行转化完成预处理。这部分是通过DOM树完成的。同样也是一个Map/Reduce过程。将转化后的 xml保存在 HDFS上的 xml文件夹中。
这样,这 5个功能模块就构成了一个基于 Hadoop的分布式爬虫系统。从生成待抓取队列开始循环执行 CrawlerDriver、ParserDriver和 OptimizerDriver以完成各层网页抓取,跳出循环后,执行 MergeDriver和 HtmlToXMLDriver预处理工作。其中,循环次数是通过预设定的参数“爬取层数 depth”和“待抓取队列是否为空”来控制的。
7.2爬虫系统的框架设计
爬虫系统有四个存储结构:待抓取 URL 库、原始网页库、链出 URL库和 xml库。这四个存储结构都是存在于 Hadoop的分布式文件系统以 HDFS为载体。下面详细说明这四个存储结构:
(1)待抓取 URL 库:存放当前层需要抓取的 URL集合,实际上就是一个记录着待抓取 URL的文本文件,其中 URL之间以“\n”为分隔符。在第一层抓取之前,这个文本文件是用户提交的 URL种子集合作为爬虫进入互联网的入口。
(2)原始网页库:存放每一层抓取下来的原始网页。这里的网页是未经过任何处理的 HTML 信息,其存放形式是 key值为 URL,value值为 URL对应的网页HTML信息。
(3)链出 URL 库:存放每一层解析出来的链出链接,其存放形式是 key值为 URL,value值为 URL对应网页包含的链出链接集合。
(4)xml库:存放所有层抓取下来的网页经过转化的 XML信息。这里的转化相当于对 HTML信息的预处理。其存放形式是 key值为 URL,value值为URL对应的网页的 XML信息。
上述 5个功能模块分别完成不同的功能,且他们都是多台机器并行完成它们的工作,而这四个存储结构分别存储着各个功能模块生成的结果。