标签:style class blog code java http
定向数据网络爬虫和搜索引擎项目设计
(新闻数据抓取、分析、加工、检索)
版本号: v 1.0.0
编写人: 张 文 豪
日 期: 2014年6月10日
文档说明:这个文档还在编写之中,文章中很多写在“保留”二字的不是每月东西,而是没有写。虽然没有具体实现,但是我觉得我把我的经验和思考都写进去了。虽然对于读者来说这个文档相当粗糙,但是是我一个很看重的东西。如果真的有人愿意认真阅读这篇文章,我会很开心和大家交流探讨,欢迎留言和联系我。
zhangwenhao3@sina.com
文章来源:http://www.cnblogs.com/zhangwenhao/p/3785975.html
最后更新日期:2014年6月13日
版本说明:
V1.0.0
新建文档;
现在文档描述了很多很多实现的点,但是这个版本不少已经实现了,但是还有不少模块处于开发过程中。但是关键点都已经设计到了,不同的读者可以有不同的实现。如果看到了(保留),只说明作者没有写,不代表没有。
这个版本虽然粗糙,但是写上去的都是作者经验中的最核心部分。
定向数据爬虫其实就是一个网络信息深度采集的一个实现。系统核心是数据挖掘(信号分析)和对应自动处理模型建立。
本系统的开发出发点是解决互联网新闻和新闻相关的定向数据抓取和处理,但是本系统并不限定于新闻数据本身。本系统立足是一切面向互联网数据的垂直数据抓取[①]。
系统特点:体量大,宽匹配,精确抓取。因为数据大,可以后期进行深度数据挖掘工作,也注定我们系统是一个大型系统。因为大量的参考了互联网网页形式,设计获取目前也是全面,因此能匹配互联网上的几乎所有页面。因为每一个敏感信息量我们都有不同的获取实现,我们能实现数据的精确抓取。
这份系统设计稿完全处于作者本人之手。由于作者水平有限,这么大的系统肯定会有不合适的地方,因此我主张一步一步实现。这个系统设计基于作者的第三个版本的实现。
这份系统设计也许在程序设计部分很多实现的地方是不合适,需要大家共同完善。但是我主要主张的是这个系统的设计思想。这是我系统的一个出发点,也是我在开发过程中积累起来的经验。因此这没有具体实现,提出来的注意的点也是对今后系统开发很有帮助的。
数据获取部分:全网进行数据抓取,判断出新闻页面,处理出新闻内容和相关内容。
数据分析部分:新闻分类(多元分类),新闻权重热点分析(其实是url和检索权重分析)。
数据加工部分:新闻要素加工(主要对接现有关键词、人物等属性,不过现在这部分处理有待改善),新闻图片视频加工,新闻相关度加工(自动处理出相关的新闻,这部分也类似于新闻校重)。
数据检索部分:不单纯是一个全文检索,需要有信息量权值的一个检索。
这个系统本身是是一个类似搜索引擎的数据获取分析和挖掘的系统。在设计系统的时候需要实现知道系统需要处理基本元素。也就是说需要知道我们这个系统所要处理的数据和关系。
本系统依托是大型网站基本的流量环设计模式,同时因为是定向数据挖掘,我们的spider暂时只采用深度优先模式[②]。本系统目标是通过简单建模,实现初步的机器自动分析功能。
本系统的总体出发点:定向数据。因此我们系统对于特定数据会很敏感,属于一个垂直加工平台。我们需要的数据要保证准确性,需要为后期加工预留很多加工接口,这个也决定了我们系统和百度等搜索引擎的spider在实现上会有明显差异。我们这系统立足于深加工。
我们涉及到的需要处理的数据包含了:url(含参数)、页面头信息、meta信息、页面结构和内容。
url可以获取url分级结构,并且可以帮助我们判断一个页面是否是我们想要的新闻页面,或者是我们想要的一个新闻分类页面页面。
页面头信息可以帮助我们获取一个页面的更新频度,对应时间也是我们spider执行抓取操作的时候一个很重要的参考标准。更新频度可以帮助我们获取聚类页面的权值,对应的权值也可以适当的附加到下属的叶子页面。
Meta信息除了也帮我我们知道更新信息,本身可以获取对应网站seo所处理处理来的类似关键词或者该页面是否重要等信息。
页面结构本身可以帮助我们准确的获取页面对应的内容。由于我们感兴趣的新闻页面的页面结构本身具有一致性,这个也为我们进行spider的内容维护带来方便。
备注:同所有的spider一样,对于ajax和flash相关的内容都不能很好的获取,这个需要额外的代码和人工维护。
我们涉及到需要处理的关系有:url的相互指向关系。
url相互指向关系包含了分类信息,也可以通过这些信息计算出对应页面的权重。
上一节将的是我们说的数据和关系是来源数据和关系,为了实现我们数据抓取和分析的目标,需要处理出我们需要的数据和关系。
我们需要处理出的数据有:spider数据字典维护、spider执行模板、数据分类。
spider数据字典是当前定向搜索引擎广泛存在的,这个字典表需要实现人工维护和系统自动维护。比如某些关键信息,在页面上是一个图片,但是我们需要让这个对应成一个字符串,就需要人工或者图像文字识别技术(这个技术已经测试过,效果不好,不能作为标准数据产生)。再比如在页面上只有一个url信息,但是我们知道这个url还能代表一些其他信息,也需要一个数据字典维护。
上面所所说的数据字典主要指在获取我们需要的新闻数据的时候需要的维护数据字典。类似人物库等数据字典可以由其他模块实现,暂时不在我们的讨论和设计范围。
Spider其实就是一堆的功能模块,这种模块化编程本身是大型系统所推崇的设计。而且根据我们系统面对的实际情况,互联网上的数据表现形式和不同数据的组织结构是多种多样的。因此我们需要有不同的spider模块来获取这些不同的数据,处理不同的结构。
拥有了上述的spider处理模块就相当于拥有了不同的积木。而spider执行模板其实就是一个将上述积木组合起来的一个组装模板。这个组装模板也是需要人工和系统自动(主要实现)维护的。
这里讨论的数据分类不是指新闻的归类。主要指获取数据的时候需要的页面分类和url等信息的分类。
页面分类对于我们的系统非常重要。我们数据字典的系统自动维护和spider执行模板自动维护,都需要一个基本的数学建模,实现简单的机器学习(不讨论这个机器学习概念,后面自己讨论程序实现)。实现了上述数据的自动维护,其实就是实现了一个通过页面自动找到spider执行模板和其他相关信息量的过程。有了这个分类我们就能做到定向数据抓取。
url信息分类是我们系统能获取到的成本最低的分类。这个本类本身就包含了绝大多数的分类信息,但是不少情况下这个分类不能准确的指向一个具体的分类,因此还需要页面信息分类的辅助。页面信息处理出来的分类成本较高。
这里所说的程序设计解决的不单单是指获取一个页面上面的内容,我们需要考虑的是一个数据获取的整体流程。
为实现这个流程,同时结合上一章节所说的我们需要关注和需要处理出的数据,归纳出我们要解决以下问题:
细化的具体实现,包含以下模块:原始信息获取模块,页面分类模块,结构解析模块,spider执行模板生成,具体数据获取模块。这些模块将在下面具体介绍。
先说思路不画图,孙健知道我描述的整体框架。
说有模块大体按照Hadoop结构模式设计(不是分布模式),目的提高我们系统的并发性。因此我们系统会包含这些模块:所有的执行某个特定功能的程序模块,所有中间数据的一个数据池(可以认为是缓存也可以认为仓库,这些数据很多也需要存在于数据库中,有一个数据同步过程),所有认为和数据仓库的额一个统一管理模块(肩负不同任务的调度,需要控制任务的启动关闭和数量多少)。
这个模块准确的讲就是通过url准确获取网页原始数据。在这个地方,需要注意页面重定向和iframe。这些页面所获取的内容,也是需要获取的原始信息。
具体设计图稿暂时不画,说功能点。程序结构主要靠说。
使用httpclient相关jar实现,具体代码在实现的时候需要考虑以下方面。
如果使用同一个ip进行数据抓取,会被对方服务器封ip,因此需要有很多上网代理并且要有对应的代理管理逻辑。
请求数据的时候,除了url以外,需要传请求头信息,比如最后更新时间,浏览器版本,请求编码,url来源等信息。如果这些数据头都不提交的话,某些网站会认为是不友好的请求甚至返回不正确的数据。
其中最后时间是上一次请求的Last-Modified参数。来源url传上一个url来源就好了。
需要登录的网站往往需要有一个登录类,并且将获取到的cookie储存到本地,并且在今后提交的时候需要一起提交。
处理乱码处理主体有2种方式。
第一种是对于html、xml、css和js[③]等如果能找到编码格式,因为一般英文不会是乱码,因此可以去匹配出编码字符串,如果和事先的解析编码不一样,就用新的编码解析一下。
第二种是将获取到的流按照字获取前面一部分(通过标识符处理出来)。然后统计出来字的长度都是2字节的,就使用gbk解析。如果发现有很多字长度是3字节。就任务是utf-8。
由于字符编码的兼容性,使用gbk和utf-8就能处理出几乎所有的编码。除了上述2种编码,还有少见的unicode编码,这个需要特殊处理。
由于我们能很容易的统计出一个spider执行模板所对应的页面分类使用的编码格式,因此我们采用第一种处理方式效率会更高。
这个模块的spider总的来说有2个spider,第一个是进行url获取的spider(一律深度优先),另外一个是定向数据获取(需要获取除url以外的所有信息,甚至需要包含一些在页面上不能直接获取的数据的获取)。
使用多个spider线程,从一个种子页面(例如搜狐首页)出发进行全局的url获取,并且通过url的分析处理(下面会具体讨论url分析处理的具体实现,包含聚集页面的获取和页面的评分规则)找到我们需要进行抓取的新闻页面。将这些url和信息都会存在数据库中,并且需要将这些数据放到一个内存中的数据仓库中(key-value形式储存)。
同时又有多个spider线程,在上一个任务池中找到一些具体的url。然后获取网页数据,并且通过spider模板进行具体数据的解析,封装成我们的所需要的数据对象。然后进行数据存储,和新的任务池存放。
url分析模块是需要获取到我们需要抓取的url类型,同事也需要获取到有新闻聚集的页面。这里我们需要对url样式进行分析,这个分析其实就是数据分类章节中的url信息分类。
通过url需要处理出来一系列归类。这个本身需要一个建模过程来处理。处理如下,根据url中的host、“/”隔开的分级、日期、前缀后缀、页面id、参数等信息进行初步分类。这些分类是根据经验预判的分类,在当数据积累过后,需要对上面的分类进行维护。
维护需要包括对分类的合并[④]、标记删除、标记是否是新闻页面、标记分类对应的url数量等信息。
这里还有一个地方需要特别注意,需要对url的参数进行的处理是不一样的,需要对一个分类的参数进行标注,区分出什么参数是跟我们页面内容有关的,需要保留的,什么样的参数是我们要舍弃的。对于我们要舍弃的参数,我们再保存的时候就不需要保存了。
今后我们还要判断出一个参数或者后缀是否是一个分页编号。
在上一节的url结构分析当中,已经将url结构进行了分类。意味着通过一个url就能找到一个对应的分类。这时候我们要通过url分类判断出一个url对应的页面是否是我们要抓取数据的新闻页面,同事也要判断是否是一个新闻集合页面。
从现阶段开发设计来说,我们进行一个简单的建模,帮助我们分析url:
l 给定的种子页面(或集合)从属的大多数页面我们都是新闻页面。因此当一个url结构所从属的url数量众多并且增加频繁,就认为这个集合下面的url是新闻页面。
l 给定种子页面站外的url对应的页面是我们不需要的页面。
l 新闻聚合页面会包含很多新闻页面,并且更新频繁。
对于上面的建模,需要做一些反馈维护:
l 当某个大分类是有频繁的出现新页面,但是我们不感兴趣,或者我们不能获取到合适的内容,需要进行标识。这个反馈帮助我们更精确的判断新闻页面。
在处理url的时候,需要记录一些关键信息,这些信息在今后处理抓取和处理数据的时候非常重要。
l 页面相互链接关系。页面和页面链接有一个指引关系,这些关系我们要忽略掉站外链接,同时要根据meta和a标签中标准的nofollow标签判断是否要跟踪一个url链接。
l url页面的Last-Modified参数,这个参数在请求的时候需要提交,因此要记录最后一次请求Last-Modified参数。
l 需要记录一个url页面的成功请求次数(返回304的时候不记录),并且根据访问频率和请求成功的统计值决定这个url多久访问一次(适用于新闻集合页)。
页面结构直接决定了页面的类型,页面的内容获取途径。
在上面的url分析中,如果一个url分类出现频率特别多,我们就任务这个url是我们感兴趣的页面。然后我就需要对这个些url的原始页面数据的结构进行分析。结构分析比较的是div、span这样的标签结构。
如果这一个url分类的页面我们都能获取到正文和标题,那么着一类就是我们需要抓取的,但是无法获取这些信息,我们需要标注这个分类不是新闻页面。
如果这一个url分类下面的url页面的结构明显不一样,但是都可以认为是新闻页面。那么着个url分类下面还需要被分类,这个分类就我前面提到的页面分类。我们需要将这个页面的标志信息进行提取,并将这些标志信息储存为一个分类。
页面结构我们可以理解为很多页面区域,这些区域都有一些信息量,但是我们系统不会自然语言解析,不能像人一样的区分出页面区域具体表达的意思。但是我们能通过建模,实现数据挖掘,来判断什么样的区域有我们敢兴趣的信息量。
建模规则和我们建模的出发点:
l 我们的定向抓取的数据是一个网站数量最多的数据。
l 不同的页面对应的我们要抓取的数据是差异很大的。同理,我们认为当一个区域频繁的出现相似的内容,我们认为这样的数据是页面相关链接等类似数据,不是我们要的核心数据。
l 页面的核心数据应当和标题。Mete中的关键词概述等信息相一致。
l 页面的核心数据,应当基本是聚集在一起的。同事根据很多页面的统计,这个区域的文字也是最多的(简化规则,准确描述是下一条规则)。
l 如果进行文字处理,我们敢兴趣的区域应该是信息量最大的区域,具体文字处理在后面描述。
定向数据(这里指新闻数据)在上面的流程中已经获取到了原始数据,但是这个原始数据是页面展示数据,与我们数据库的存储结构和展现形式是完全不一样的。需要通过各种手段将这些数据获取到。结合互联网页面数据的具体情况,我们需要以下处理模块。
Html页面有一定的页面布局结构(这个结构也是我们今后自动分析spider执行模板的关键所在),根据页面结构定位我们要的内容是一个常见做法。除此之外,页面不同机构内容的数据分析,可以更精确的帮我们找到对应的内容。
这里需要通过页面结构匹配数据使用jsoup处理。匹配数据过程类似选择器选择节点过程,可以通过id,class和父子节点关系定位到具体数据内容。
这种获取方式可以获取到类似标题、正文、导航栏、关键字、概述、发布日期、来源、编辑、图片集、视频等信息。这些信息现在还是和页面展示一致的,不完全符合我们的要求,因此我们认为这个处理是为一级处理。下面设计的加工过程属于第二级数据加工。
直接匹配的数据还要经过再加工,才能是我们标准数据。设计到的地方有:
l 去除不必要的文章类模块。例如有的网站页面在正文内有广告模块,或隐藏的来源信息模块,或一些相关链接文集等模块。
l 去除我们不需要的a标签。涉及情况有标题里面有链接,导航栏有链接,文内有链(例如新浪腾讯会加工出新闻里面的一些名人微博链接)。
l 去除不必要的文字。例如新闻里面有一些加工过的标签,比如有“微博”二字,例如欢迎使用什么什么客户端,例如什么产品欢迎你加入,还有一些版权信息。
在新闻里面,有很多图片集新闻。大部分图片集新闻都使用js实现,在这里我们只讨论通过js实现的图片集,因为这样的图片集占绝大多数。通过分页实现的图片集会在今后提到文章分页的时候讨论。通过flash和flex实现的图片由于暂时没有获取数据的实现,我们不处理。
图片集会可能出现在文章内部的一个部分,也可能出现在一类专门的页面当中。不管怎样,图片集都包含了2个要素:一个是有序的图片,一个是对应的图片文字描述,图片文字描述又包含结尾统一描述和一张图片一个描述。而上述2个要素在实现的时候会发现所有网站都通过一个专门的ajax请求去获取页面图片信息和描述信息,然后通过js解析,生成图片集功能(本来作者预想也会有网站通过iframe请求实现图集,第一是我们发现这样实现的图集,第二是这样的图集其实我们更好处理,因此我们在这里也不讨论)。
通过上述介绍,我们在处理图集的时候,主要是要获取到图集请求,然后通过这个请求出来的数据获取信息。然后需要有一个新闻拼写规则,将图集图片和描述和已经有的正文信息进行有机的组合。
要完整的实现这个要求需要一个java处理js的模块,并且要模拟出用户的操作。这个成本较大,已经实现的是一个简单版本。
我们需要的定向数据可能有分页暂时的情况。例如较长的新闻,或者一些分页展示的图集。这些带分页的数据,细分有以下几种方式,我们都需要有代码具体实现。
l 在页面有一个或多个分页导航栏,这些导航栏有页码跳转的信息。需要注意的时候,不少网站在文章最后一页过后点击下一页其实也是有新闻页面出现的,但是是不同的新闻页面了,这个一定要注意处理。
l 通过点击加载更多按钮,通过一个一个ajax请求实现分页加载,其本质和上一种情况是一样的,需要处理出分页url进行获取。
l 通过点击加载更多按钮,然后去缓存数据里面,或者是显示某些标签实现的分页,这个需要我们事先获取到缓存数据然后进行分页数据处理。这种情况类似于图片集的处理方案。
注意:不管是那种情况的分页,网站设计者基本都会在url上通过一个参数对分页进行标识。目的是为了保证同一个url在打开后能出现同一个页面,就是说用户在看到第几页后,将这个url粘贴给其他人,其他人打开的也会是第三页。这个url本身也能为我们处理分页带来方便。
上面说的是我们获取分页数据的情况,在我们获取数据后,还需要根据页面展示对分页数据拼装回去,这就需要涉及到很多掐头去尾的操作。
我们要做到定向数据获取,数据准确和数据的高处理度是我们系统的最终目标,宽匹配是不能达到我们的目标的。但是前面说了,互联网展示形式千奇百怪,我们需要有一个spider执行模板来控制所有的执行流程,和处理过程。
在我们获取到很多数据后,必然有一个数据组装的先后流程。必然具体的有要先字符编码处理,然后进行分页数据拼装,然后进行拼装后的正文内容去除不必要a标签的处理。这个处理流程本身就需要用spider执行模板进行控制。
这个处理流程模板除了要标明不同操作的先后顺序,还需要标注出具体位置需要调用的处理模块。
具体实现(保留)
数据流程处理过程中,已经标注了数据处理的模块,可是执行模块也需要很多数据信息来知道具体的执行过程。比如说通过结构获取具体数据模块就需要传入一个结构模板来描述如何匹配对应的数据。
这个更多的数据信息其实就是具体的执行操作。
具体实现(保留)
上面2节中讨论了如何通过spider执行模板来获取数据,但是如何产生spider执行模板是我们要讨论的重点中的重点。
实现思路:要实现这个spider模板的自动生成,其实就是一个数据挖掘的过程。因此我们需要一个数据积累过程,和一个数据获取建模。数据获取建模前我们要确立一些核心规则:
l 人工维护的模板我们认为是最标准的,如果一个分类(这里分类不单独指url分类)有人工维护的模板,相近分类可通过这个模板去匹配,如果结构上大体一致,我们就认为新结构是一个合格的模板。
l 在参考人工模板的同事,我们需要结合页面结构分析模块中分析出来的页面敏感区域。并且我们认为这些区域中文字最聚集的部分是正文(也有其他文字处理),认为title标签和h1和正文的文字处理后的信息量是相似的。我们将相似的部分认为是我们这篇新闻的标题。
l 我们认为正文或者标题里面出现频率明显偏高的词汇或句子(出现频率是一个简化概念,具体需要文字处理,但是一个词大规模不合时宜的出现,那个词的信息量在一类文章中肯定是很低的)是没有信息量的词汇和句子,在实际产生数据的时候我们需要去掉。
l 当一些也判断为了页面敏感区域,但是这些区域不能像标题,和正文一样判断的时候,我们可以通过其他规则进行数据侦测。
l 我们判断出了一个区域和我们的数据对应过后,我们要将这个区域的结构通过一个方式表达出来,今后具体数据可以安装这个表达方式进行数据获取。
实现过程:(保留)
在前面的章节中,我们已经发现页面结构分析,spider模板产生等核心模块都依赖于一个关键的处理,这个就是需要通过对区域文本进行信息量的处理。文本处理的结果其实就是一个数据挖掘中的一个基本评分标准。有了这个标准,我们除了判定我们需要捕获的信息,同时这个处理本身就能分析出新闻的很多相关信息,比如关键词,摘要,文章相似度。最重要的是,这个文本信息是我们接下来进行数据检索基础。在这个基础上我们加上自然语言识别等模块,就是一个百度搜索引擎了。
文本处理需要对从词、词项、文本和文档的统计、结构等进行统计分析,然后根据相关模型处理出信息量。然后就能进行相关处理(除结构统计外都实现了,保留);
(这个除了词义解析没有写,其他都实现了,保留)
(简单但是,保留)
(简单但是,保留)
我们的新闻根据页面关系和文章内容,可以处理出很多相关内容。比如文章关键词,新闻的发生地点,图片和新闻等关系。
在文字处理部分,我们需要使用到上一章的文本分析。我们可以分析文本的相关信息。(有简单版本,保留)
此处是指通过url和新闻相关度简历的新闻分类库。(有简单版本实现,保留)
新闻图片处理就是在数据库中对新闻图片进行特征值进行保存。
简单的说需要对图片进行灰度化、锐化然后处理出特征向量(其实是频谱信息),将这个具体的向量特征值放在数据。具体检索的时候比较2个图片的特征向量就好了。如果公司真的需要做这一块的话,那么久需要保留颜色信息,除了基本形状特征值外,还需要处理出图片当中的所有小信号。找一个通信行业做图像处理的来好好设计一下吧。
具体实现(保留)。
这个检索不是一般程序说的全文检索,是一个有匹配度权值的检索。其实就是文字处理的一个应用。
(有简单版本实现,保留)
这里的数据库设计主要安装关系型数据设计,但是具体的设计其实是按照我的程序数据对象来设计的,准确的说是面向对象设计的。如果要采用非关系型的数据库设计,那么也建议按照程序的对象结构进行拆分,不要什么都放在一个集合,这样会给后期程序带来很多不必要的花销和麻烦。
具体设计(保留)
(保留)
本系统完全出自于作者之手,受限于作者水平,会出现用词不是很准确的地方。有的词汇也是为了表达作者想法使用的。因此对于前面没有解释的一些词汇,在这里做一个统一解释。同时也对一些说法进行解释。
[①] 垂直数据获取指不像百度这样的搜索引擎,百度很多数据其实是不敏感的,但是我们很多数据是必须要处理的。百度是一个宽匹配,我们的系统是一个精确匹配。
[②] 深度优先抓取表示在遍历互联网数据的时候,根据url的的映射关系,一级一级的进行抓取。由于我们只有新闻页面才会去获取具体信息数据,所以深度优先其实是指url关系分析过程。
[③] 这里需要说明的是,还是有不少的页面的数据不是直接通过url页面请求过来的,有的网页展示的数据会通过xml、js文件、和css文件下载下来。
[④] 因为事先的url预判分类已经很细了,会发现今后的url分类操作今后只有合并的情况发生。一个url分类对应的页面有很多种情况的时候,也不能拆分,需要通过页面分类实现。
定向数据爬虫和搜索引擎(Directional Spider)设计文档,布布扣,bubuko.com
定向数据爬虫和搜索引擎(Directional Spider)设计文档
标签:style class blog code java http
原文地址:http://www.cnblogs.com/zhangwenhao/p/3785975.html