网络蜘蛛设计文档
- 格式:doc
- 大小:253.50 KB
- 文档页数:11
网络蜘蛛项目开发报告孙君意中科院计算技术研究所sunjunyi@摘要:本项目基于微软.Net2.0平台,用C++/CLI 编程实现了网络蜘蛛(Web Spider)。
该蜘蛛可以访问用户指定的一个或多个站点,遍历站点内的所有网页,并且把网页分解成标题、纯文本内容、网页大小等属性,然后保存在ACCESS 数据库中。
关键词:网络蜘蛛,搜索引擎,.Net2.0Abstract:This program is a Web Spider which was implemented with C++/CLI language based on Microsoft .Net 2.0 Framework. The spider can travel on one or more sites given by user, and split the web page into elements of title, plaint text, page size and so on, and then save them into an ACCESS database.Key Words: Web Spider, Search Engine, .Net2.0目录1.项目背景 (3)2.需求分析 (3)2.1 下载网页 (3)2.2 分解网页 (4)2.3 遍历网络 (4)2.4 存储网页 (4)3.概要设计 (5)3.1 技术选型 (5)3.2 系统架构 (5)3.3 数据库结构 (6)4.详细设计 (6)4.1 网络IO模型 (6)4.2 文本编码 (8)4.3 用正则表达式分解网页 (8)5.程序截屏 (10)6.开发及运行环境 (11)7.不足和展望................................................................................. 错误!未定义书签。
8.致谢............................................................................................. 错误!未定义书签。
9.参考文献..................................................................................... 错误!未定义书签。
1.项目背景网络蜘蛛即Web Spider,是一个非常形象的名字。
把互联网比喻成一个蜘蛛网,那么Spider程序就是在网上爬来爬去的蜘蛛。
网络蜘蛛是通过网页的链接地址来寻找网页,从网站的某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止。
如果把整个互联网当成一个网站,那么网络蜘蛛就可以用这个原理把互联网上所有的网页都抓取下来。
2.需求分析本节内容将简要的分析一下一个网络蜘蛛应该具有的基本功能,包括:下载网页、分解网页、遍历网络、存储网页等。
网络蜘蛛的技术难度并不是很高,但是要开发一个速度快、稳定性高的网络蜘蛛还是要下一番功夫的。
2.1下载网页网络蜘蛛最基本的功能是能够从给定的网址下载网页。
这个过程看似简单,但却要考虑几个问题。
首先,要解决网页的编码问题,Internet联通世界各个角落,每个国家和地区的网站使用着不同的编码,即使同在一个国家的网站其使用的网页编码规则也不尽相同。
比如说在我国,有些网站使用UTF-8编码,有些则使用GB2312。
如果Web Spider对网页的编码不加判断的话,很有可能出现乱码。
其次,网络的访问速度相对与CPU的运算速度来说是非常慢的,因此,如果Web Spider被设计成单线程的阻塞模型的程序的话,其抓取速度必然不能让人满意。
可以考虑采用多线程或采用其它的IO模型来提升蜘蛛的抓取速度。
第三,网络蜘蛛只下载网站中的文本信息(如:HTML页面、ASP、PHP、JSP等等),并不下载图片、软件、视音频文件等等。
2.2分解网页网络蜘蛛并不是单纯的把网页批量下载到本地硬盘的工具,它的目标是从网页中提取一定的结构化的信息,比如说网页的标题、网页的内容、网页的大小、网页中的链接等等。
网页的内容并不是简单地指网页的HTML代码,因为大部分的HTML标签以及JavaScript代码对我们的后期要进行的查询工作等都是冗余的,所以应该将它们剔除。
网页的标题并不是简单地指网页源码中Title标签内的文本,而是指网页源码中最能概括出该网页内容的某句话。
提取网页的链接也不只是简单地提取HTML源码中所有“href”后面的URL,还包括框架页面,以及脚本中的自动转向页面地址。
2.3遍历网络本项目要开发的蜘蛛与Google等大型搜索引擎的蜘蛛不同,它的访问范围并不是整个互联网,而是用户指定的一个或多个网站,因此蜘蛛在遍历网络的时候不能够漫无边际的爬行,而是在制定的范围内。
网络遍历的算法可以是深度优先搜索、宽度优先搜索、启发式搜索等算法。
笔者在开发中使用了启发式搜索,在3.2节中会有详细的叙述。
2.4存储网页由于本项目只是专注与网络蜘蛛的实现,并不需要优化的全文检索存储方案,为了便于测试,可以选用ACCESS数据库,它简单易用,可以胜任小批量的查询工作。
网络蜘蛛把网页中的相关信息抽取出以后插入到数据库的对应字段中。
3.概要设计3.1技术选型本项目选用的开发语言是微软的C++/CLI,它是静态C++对象模型到CLI 的动态组件对象编程模型的捆绑。
简而言之,它就是你如何用C++在.NET中编程,而不是C#或Visual 。
笔者选用C++/CLI主要基于一下几点考虑:1.可以使用.Net框架中的丰富的类库,如字典结构、正则表达式等。
2.可以方便地调用Win32 API,这一点比C#好。
3.有强大的IDE:Visual Studio 2005,提高了开发速度。
3.2系统架构图3.1 网络蜘蛛系统架构图如图3.1所示,站点列表里面存储着用户指定的网站首页URL,程序运行后将其插入到优先队列,下载模块从优先队列里取出URL,把对应的网页下载下来,然后将网页源码交给分析模块,分析模块对网页进行分解,分析模块维护着一张字典或Hash表,记录着所有已经访问的URL,然后分析模块将所有未访问过的链接URL提取出来插入到优先队列,再把提取出的网页的标题、内容、大小等信息存入数据库。
整个虚线方框里的过程是不断循环往复的,直到优先队列为空。
本项目用优先队列来实现启发式搜索,优先队列中元素的优先级指的是URL的重要程度,它取决与URL的层次,比如说比/news/2006/05/1.html的优先级要高。
当然,优先级也可以由用户来指定。
3.3数据库结构本项目的数据库结构很简单,总共两个表,一个是站点列表,一个是网页存储表。
表3.1 站点列表表3.2 网页存储表4.详细设计本节将主要介绍笔者在开发的过程中遇到的实际问题以及解决方案。
4.1网络IO模型前面的章节已经提到过,网络的访问速度相对与CPU的运算速度来说是非常慢的,因此,如果Web Spider被设计成单线程的阻塞模型的程序的话,其抓取速度必然不能让人满意。
可以考虑采用多线程或采用其它的IO模型来提升蜘蛛的抓取速度。
笔者在提升Web Spider抓取速度的过程中并没有使用多线程方式,而是在网络的IO模型上下功夫,采用了IOCP(IO完成端口)。
事实证明效果不错。
从本质上说,完成端口模型要求创建一个windows完成端口对象,该对象通过指定数量的线程,对重叠I/O请求进行管理,以便为已经完成的重叠I/O请求提供服务。
首先要创建一个I/O完成端口对象,用它面向任意数量的套接字句柄,管理多个I/O请求。
调用以下函数创建完成端口对象:HANDLE CreateIoCompletionPort(HANDLE FileHandle,// 同IOCP关联在一起的套接字句柄HANDLE ExistingCompletionPort,// IOCP句柄ULONG_PTR CompletionKey, // 完成键DWORD NumberOfConcurrentThreads // 在IOCP上,同时允许执行的线程数量);该函数有两个作用:(1)创建一个完成端口对象(2)将一个句柄同完成端口关联到一起然后就要创建一定数量的工作者线程,以便在套接字的I/O请求投递给完成端口后,为完成端口提供服务。
更多的细节请参看笔者提交的代码WebSpider.cpp。
为了进一步提升蜘蛛的抓取速度,引入了多进程机制,相当于有多个WebSpider.exe在同时运行,这在设计中要充分考虑同步和互斥的问题,在调试的过程中花费了不少时间。
经过测试,在城域网内(清华、北大、中科院各院所的网站),蜘蛛的抓取速度可以达到平均每分钟1400张网页。
由于上网流量的限制,我未能在更大范围内进行测试。
4.2文本编码判断网页的编码规则是比较简单的,但是正确率往往达不到100%,就算我们平时使用IE浏览器也会偶尔看见乱码。
本项目的做法是依据网页源码的代码片段中“<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />”的charset属性值来判断网页的编码。
这种做法的准确率可以达到95%。
一般正规的网站的网页代码中都会有这段信息。
如果没有此信息,就用GBK编码。
4.3用正则表达式分解网页分解网页的实现主要是对字符串进行匹配和替换,用传统的方法编程实现的话代码量相当大,在本项目中利用了.Net框架中的正则表达式类,编程者只需要根据实际需求写出正确的正则表达式就能够完成一系列复杂的文本匹配和替换的工作。
一个正则表达式,就是用某种模式去匹配一类字符串的一个公式。
很多人因为它们看上去比较古怪而且复杂所以不敢去使用,不过,经过一点点练习之后我就开始觉得这些复杂的表达式其实写起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作压缩在几分钟(甚至几秒钟)内完成。
正则表达式被各种文本编辑软件、类库(例如Rogue Wave的tools.h++)、脚本工具(像awk/grep/sed)广泛的支持,而且像Microsoft的Visual C++ 2005这种交互式IDE也开始支持它了。
表4.1 正则表达式的元字符及其描述元字符描述.匹配任何单个字符。
例如正则表达式r.t匹配这些字符串:rat、rut、r t,但是不匹配root。