- 浏览: 240939 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (172)
- J2SE学习模块 (35)
- Oracle学习模块 (12)
- Jsp学习模块 (11)
- Servlet学习模块 (1)
- Tomcat 模块 (4)
- Struts1.x学习模块 (5)
- Spring学习模块 (2)
- Hibernate学习模块 (11)
- XML学习模块 (1)
- UML学习模块 (0)
- 算法学习模块 (6)
- 设计模式模块 (2)
- Mysql学习模块 (1)
- SQL_Server学习模块 (8)
- 项目开发模块 (10)
- 搜索引擎 (14)
- 开发工具的使用 (2)
- 面试题集 (7)
- 开发工具 (8)
- Linux (5)
- JavaFX模块 (1)
- 程序与人生 (4)
- 计算机网络 (6)
- EJB学习模块 (1)
- javascript常用模块 (2)
- 英语学习 (1)
- 程序变量命名的几条法则:匈牙利命名法 (1)
- 驼峰式大小写 (1)
- 帕斯卡命名法 (1)
- Jquery控制图片宽度及高度 (1)
- 喜讯--FireFox7.01已经支持CSS中 text-overflow ellipsis 属性 (1)
- 遍历 Map 的三种 常用方法 java (1)
- JDK自带工具Jstat (1)
- 提高 Oracle 查询 效率 建议 (1)
- 常用工具 (1)
最新评论
-
a465492689:
挺好,谢谢分享
存储过程 -
huangqinghe:
ding 顶~~~
Intellij Idea12 中文乱码问题总结 -
Redpick13:
楼主好人啊,有耐心
Java中的二维数组的定义与学习 -
dandongsoft:
神鼎飞丹砂
java.lang.NoClassDefFoundError: org/apache/lucene/index/memory/MemoryIndex -
devil__lord:
不错讲得很清楚 color=#cff
Java中的二维数组的定义与学习
---- 一、引言
---- 随着Internet的飞速发展,人们越来越依靠网络来查找他们所需要的信息,但是,由于网上的信息源多不胜数,也就是我们经常所说的"Rich Data, Poor Information"。所以如何有效的去发现我们所需要的信息,就成了一个很关键的问题。为了解决这个问题,搜索引擎就随之诞生。
---- 现在在网上的搜索引擎也已经有很多,比较著名的有AltaVista, Yahoo, InfoSeek, Metacrawler, SavvySearch等等。国内也建立了很多的搜索引擎,比如:搜狐、新浪、北极星等等,当然由于它们建立的时间不长,在信息搜索的取全率和取准率上都有待于改进和提高。
---- Alta Vista是一个速度很快的搜索引擎,由于它强大的硬件配置,使它能够做及其复杂的查询。它主要是基于关键字进行查询,它漫游的领域有Web和Usenet。支持布尔查询的"AND","OR"和"NOT",同时还加上最相近定位"NEAR",允许通配符和"向后"搜索(比如:你可以查找链接到某一页的所有Web站点)。你可以决定是否对搜索的短语加上权值,在文档的什么部位去查找它们。能够进行短语查询而不是简单的单词查询的优点是很明显的,比如,我们想要查找一个短语"to be or not to be",如果只是把它们分解成单词的话,这些单词都是属于Stop Word,这样这个查询就不会有任何结果,但是把它当作一个整体来查询,就很容易返回一些结果,比如关于哈姆雷特或者是莎士比亚等等的信息。系统对查询结果所得到的网页的打分是根据在网页中所包含的你的搜索短语的多少,它们在文档的什么位置以及搜索短语在文档内部之间的距离来决定的。同时可以把得到的搜索结果翻译成其他的语言。
---- Exite是称为具有"智能"的搜索引擎,因为它建立了一个基于概念的索引。当然,它所谓的"智能"是基于对概率统计的灵活应用。它能够同时进行基于概念和关键字的索引。它能够索引Web,Usenet和分类的广告。支持"AND","OR","NOT"等布尔操作,同时也可以使用符号"+"和"-"。缺点是在返回的查询结果中没有指定网页的尺寸和格式。
---- InfoSeek是一个简单但是功能强大的索引,它的一个优点是有一个面向主题搜索的可扩展的分类。你可以把你的搜索短语和相似的分类目录的主题短语相互参照,而那些主题短语会自动加到你的查询中去。使你的搜索有更好的主题相关性。同时它也支持对图象的查询。它能够漫游Web,Usenet,Usenet FAQs等等。不支持布尔操作,但是可以使用符号"+"和"-"(相当于"AND"和"NOT")
---- Yahoo实际上不能称为是一个搜索引擎站点,但是它提供了一个分层的主题索引,使你能够从一个通常的主题进入到一个特定的主题,Yahoo对Web进行了有效的组织和分类。比如你想要建立一个网页,但是你不知道如何操作,为了在Yahoo上找到关于建立网页的信息,你可以先在Yahoo上选择一个主题:计算机和Internet,然后在这个主题下,你可以发现一些子主题,比如:Web网页制作,CGI编程,JAVA,HTML,网页设计等,选择一个和你要找的相关的子主题,最终你就可以得到和该子主题相关的所有的网页的链接。也就是说,如果你对要查找的内容属于哪个主题十分清楚的话,通过目录查询的方法要比一般的使用搜索引擎有更好的准确率。你可以搜索Yahoo的索引,但是事实上,你并没有在搜索整个Web。但是Yahoo提供了选项使你可以同时搜索其他的搜索引擎,比如:Alta Vista。但是要注意的是Yahoo实际上只是对Web的一小部分进行了分类和组织,而且它的实效性也不是很好。
---- 搜索引擎的基本原理是通过网络机器人定期在web网页上爬行,然后发现新的网页,把它们取回来放到本地的数据库中,用户的查询请求可以通过查询本地的数据库来得到。如yahoo每天会找到大约500万个新的网页。
---- 搜索引擎的实现机制一般有两种,一种是通过手工方式对网页进行索引,比如yahoo的网页是通过手工分类的方式实现的,它的缺点是Web的覆盖率比较低,同时不能保证最新的信息。查询匹配是通过用户写入的关键字和网页的描述和标题来进行匹配,而不是通过全文的匹配进行的。第二种是对网页进行自动的索引,象AltaVista则是完全通过自动索引实现的。这种能实现自动的文档分类,实际上采用了信息提取的技术。但是在分类准确性上可能不如手工分类。
---- 搜索引擎一般都有一个Robot定期的访问一些站点,来检查这些站点的变化,同时查找新的站点。一般站点有一个robot.txt文件用来说明服务器不希望Robot访问的区域,Robot 都必须遵守这个规定。如果是自动索引的话,Robot在得到页面以后,需要对该页面根据其内容进行索引,根据它的关键字的情况把它归到某一类中。页面的信息是通过元数据的形式保存的,典型的元数据包括标题、IP地址、一个该页面的简要的介绍,关键字或者是索引短语、文件的大小和最后的更新的日期。尽管元数据有一定的标准,但是很多站点都采用自己的模板。文档提取机制和索引策略对Web搜索引擎的有效性有很大的关系。高级的搜索选项一般包括:布尔方法或者是短语匹配和自然语言处理。一个查询所产生的结果按照提取机制被分成不同的等级提交给用户。最相关的放在最前面。每一个提取出来的文档的元数据被显示给用户。同时包括该文档所在的URL地址。
---- 另外有一些关于某一个主题的专门的引擎,它们只对某一个主题的内容进行搜索和处理,这样信息的取全率和精度相对就比较高。
---- 同时,有一类搜索引擎,它本身不用Robot去定期的采集网页。象SavvySearch 和 MetaCrawler是通过向多个搜索引擎同时发出询问并对结果进行综合返回给用户实现搜索功能。当然实际上象SavvySearch能够对各个搜索引擎的功能进行分析和比较,根据不同的用户查询提交给不同的搜索引擎进行处理,当然用户自己也可以指定利用哪一个搜索引擎。
---- 一个优秀的搜索引擎必须处理以下几个问题:1 网页的分类2 自然语言的处理3 搜索策略的调度和协作 4 面向特定用户的搜索。所以很多搜索引擎不同程度的使用了一些人工智能的技术来解决这些方面的问题。
---- 二、网络Spider的实现描述
---- 现在有很多文章对Web引擎做了大量的介绍和分析,但是很少有对它们的实现做一个详细的描述,这里我们主要来介绍一个具有基本功能的Web引擎的实现。本文,我们以类C++语言的形式来描述Web引擎如何采集网页并存放到数据库中的过程。同时描述了如何根据用户输入的关键字查询数据库并得到相关网页的过程。
---- 2.1数据库结构
---- 首先,我们要建立一个数据库表用来存放我们得到的网页。这里一般需要建立如下的表:
---- 1.字典表的建立,事实上这里是用文档中有意义的单词和它们的出现频率来代表一个文档。
---- 该表(WordDictionaryTbl)主要要包括三个字段,主要是用来存放和一个网页相关的单词的情况
url_id 对每一个URL的唯一的ID号
word 该URL中的经过stem的单词
intag 该单词在该网页中的出现的次数
---- 2.存储每一个URL信息的表
---- 该表(URLTbl)中主要的关键字段有:
rec_id 每一条记录的唯一的ID号
status 得到该URL内容的状态,比如HTTP_STATUS_TIMEOUT表示
下载网页的最大允许超时
url URL的字符串名称
content_type 内容的类型
last_modified 最新的更改时间
title 该URL的标题
docsize 该URL的文件的尺寸
last_index_time 最近一次索引的时间
next_index_time 下一次索引的时间
tag 对于网页,用来表示它的类型,比如:是text,或者是html,
或者是图片等等
hops 得到文件时候的曾经失败的次数
keywords 对于网页,和该网页相关的关键字
description 对于网页,指网页的内容的描述
lang 文档所使用的语言
---- 3.因为网页中有很多单词是一些介词和语气助词或者是非常常用的常用词,它们本身没有多少意义。比如:英语中的about,in,at,we,this等等。中文中的如"和","一起","关于"等等。我们统一的把它们称为停止词(stop word)。所以我们要建立一个表,来包括所有这些停止词。该表(StopWordTbl)主要有两个字段。
word char(32) 表示那些停止词
lang char(2) 表示所使用的语言
---- 4.我们要建立一个关于robot的表,我们在前面说过,所有的网站一般都有一个robot.txt文件用来表示网络上的robot可以访问的权限。该表(RobotTbl)主要有以下字段。
hostinfo Web站点主机的信息
path 不允许robot访问的目录
---- 5.建立我们需要屏蔽的那些网页(比如一些内容不健康的或者没有必要去搜索的站点)的一张表(ForbiddenWWWTbl),主要的字段就是网页的URL。
---- 6.另外我们需要建立一个我们所要得到的文件类型的表(FileTypeTbl),比如,对于一个简单的Web搜索引擎,我们可能只需要得到后缀为.html,htm,.shtml和txt的类型文件。其他的我们只是简单的忽略它们。主要的字段就是文件的类型和说明。
---- 其中关于停止词的表的内容是我们要实现要根据各种语言的统计结果,把那些意义不大的单词放进去。关于文档单词、URL和Robot的表的内容都是在获取Web网页的时候动态增加记录的。
---- 2.2 具体网页获取算法描述
---- 具体的网页的获取步骤是这样的:
---- 我们可以设定我们的搜索程序最大可以开的线程的数目,然后这些线程可以同时在网上进行搜索,它们根据数据库中已有的关于网页的信息,找出那些需要更新的网页(如何判断哪些网页需要更新是一个值得研究的过程,现在有很多启发式和智能的算法,基本上是基于统计规律进行建模。最简单的当然是设定一个时间范围,在某个时间范围以前的网页被重新去搜索一遍),然后判断那些网页是否在屏蔽表中,如果是的话,就从关于URL的表中删除该条记录。否则,我们就到相应的WWW站点去得到URL指定的文件(这里需要注意的是根据不同的URL的特点,需要使用不同的协议,比如对于FTP站点要采用FTP协议,对于HTTP站点要采用HTTP协议,新闻站点要采用NNTP协议等等)事实上,我们先得到关于该网页的头信息,如果该网页的最新修改时间和我们最近提取的时间是一样的话,表示该网页内容没有任何更新,则我们就不必去得到它的内容,只需要修改最近一次更新它的时间为当前的时间就可以了。如果该网页最近做了修改,我们就要得到该网页,并对它的内容进行分析,主要要包括和它相关的链接,把它们加到相应的数据库中,同时判断网页所包含的各种其他的文件,如文本文件、图形文件、声音文件和其他多媒体文件是否是我们所需要的文件,如果是的话,就把它加到我们响应的数据库中。同时要根据网页的内容提取所有的有意义的单词和它们的出现的次数,放到相应的数据库中。为了更好的描述这个过程,我们来看跟这个过程相关的主要的几个对象和数据结构。对象主要是针对三个层次来讲的。第一层是针对WWW服务器,第二层是针对每一个页面,第三层是针对每一个页面的全文的索引。
---- 2.3 和实现相关的主要类对象和功能描述下面的结构是针对一个站点来说的。
Class CServer {
主要的属性有:
char *url; //WWW站点的URL名称
char *proxy; //使用的代理的名称
char *basic_auth; //进行基本的HTTP认证
int proxy_port; //代理的端口号
int period; //再次索引的周期
int net_errors; //网络连接不通的次数
int max_net_errors; //可以允许的最大的网络错误
int read_timeout; //下载文件允许的最大的延迟
int maxhops; //表示URL可以最大跳转的深度
int userobots; //是否遵守robot.txt中的约定
int bodyweight; // 在< body >....< /body >之间的单词的权重
int titleweight; // 在< title >....< /title >之间的单词的权重
int urlweight; // 在文档的URL中的单词的权重
int descweight;//在 < META
NAME="Description" Content="..." >之间单词的权重
int keywordweight; //在< META NAME="Keywords" Content="..." >
之间的单词的权重
---- 主要方法有:
FindServer();//用来查找该服务器是否存在并可以连接
FillDefaultAttribute() //用来针对所有的WWW服务器填写默认的属};
以上的对象中的成员变量是和一个站点相关的参数的设置,我们对所有的站点有一个默认的设置,但是可以对某些站点做一些特殊的设置。这些设置可以在配置文件中设定。
---- 下面是关于文档的结构的主要的数据成员:
Class CNetDocument
主要属性有:
int url_id; //该URL的ID号
int status; //获取该文档时候的状态
int size; //文档的尺寸
int tag; //和该文档相关的标签,表示该文档是
HTML,TEXT或者是其他类型
int hops; //URL跳转的次数
char *url; //和该文档相关的URL的名称
char *content_type; //该内容的类型
char *last_modified; //最近一次的更新时间
char *title; //该文档的标题
char *last_index_time; //上次索引的时间
char *next_index_time; //下次索引的时间
char *keywords; //该文档中的关键字
char *description; //该文档的描述
主要方法有:
FillDocInfo(…) //根据数据库,得到该文档相关信息
AddHerf(…) //加入网页中存在的新的链接的网址
DeleteURL(…) //删除一个存在的网址
CanGetThisURL(…) //根据配置决定是否去得到该网页
//下面三个方法是根据不同的URL,用不同的协议去获得文档
NNTPGet(…)
FTPGet(….)
HTTPGet(….)
ParseHead(…) //如果是HTTP协议得到的话,分析头信息
ParseMainBody(…) //对获得的文档的主体进行分析
ServerResponseType (….) //得到服务器端的响应消息
UpdateURLDB(….) //更新的数据入库
} ;
---- 事实上,我们在要提取一个网页的时候,都要建立一个CNetDocument对象,然后再对这个网页进行分析的时候,把相关的内容放到这个CNetDocument的成员变量里面。下面是关于页面全文索引的结构的主要数据成员:
Class CIndexer {
主要属性有:
char *url; //我们要处理的文档相关的URL的名称
int mwords; // 我们事先设定的一个网页的最大的单词数目
int nwords; // 实际的得到的单词的数目
int swords; // 我们已经排序的单词的数目
WORD *Word; //所有单词的内容
char *buf; //我们为文档所分配的空间
主要方法有:
InitIndexer(…) //进行初始设置和分配
ParseGetFile(…) //对得到的网页进行全文索引
AddWord(…) //把网页的可以索引的单词加到Word数组中去
InToDB(….) //关于网页全文索引的信息入库
};
---- 进行网页提取前,我们要建立一个CIndexer对象,它主要是用来对网页进行全文的索引。一般来说我们只对两种类型的URL进行全文索引,一个是text/html,另外一个是text/plain。其中WORD的数据结构如下:
typedef struct word_struct {
int count; //该单词出现的次数
int code; //该单词的正常的形式,
比如单词可能为 encouraging,它的正常的形式应该为
encourage,这其实是一种对单词的stem。
即我们只取单词的主干部分。
char *word; //该单词的内容
} WORD;
---- 以下的结构是和网页中的一些链接的对象相关的一个数据结构
typedef struct href_struct {
char *href; //该链接的名称
int hops; //发生的跳转次数
int stored; //是否已经存储到数据库中
} HREF;
---- 所有需要更新的和新产生的URL都被放到这个结构中,当它的数量超过一定的范围以后,被一次性的存入数据库。
---- 关于URL的一个数据结构如下:
typedef struct url {
char *schema; //表示该URL是通过什么协议得到的,比如HTTP,
FTP,NNTP等。
char *specific; //主机的名称加上路径
char *hostinfo; //主机的名称加上相关的协议端口
char *hostname; //主机的名称
char *path; //在主机的具体的路径
char *filename; //文件的名称
char *anchor; //相关的anchor
int port; //协议相关的端口
} URL;
---- 这是针对URL的一些相关的属性的描述的一个数据结构。事实上在数据库中,我们存储的只是对网页的描述和对一些文本和HTML页面的关键词的索引信息。我们并不存储网页的实际的内容。
---- 三、用户查询实现描述
---- 关于对用户提交的查询请求的实现分析:
---- 用户想要查询某一方面的信息一般都是通过提供和该领域相关的几个关键字来进行的。
---- 我们来看一下关于用户查询的相关的数据结构和类:
---- 下面是一个关于单词和它的权值的基本结构:
typedef struct word_weight_pair
{
char word[WORD_LEN];
int weight;
}word_weight_pair;
---- 下面的类主要是用来对用户的查询进行处理和分析:
Class CUserQuery
{
char m_UserQuery[MAX_QUERYLEN]; //用户的查询表达式
CPtrArray word_weight_col;
//是关于结构word_weight_pair的动态数组
int m_maxReturnSum; //用户希望返回的最多的网页数
int search_mode;
CObArray m_returnDoc; //是关于CNetDocument对象的一个动态数组
NormalizeWord(char* OneWord); //对单词进行归整化,即Stem.
Find(char* odbcName); //进行数据库查找和匹配
};
---- 系统实现的基本的步骤如下:
---- 1.对用户输入的查询表达式进行分析。事实上,我们在前面的Spider搜索过程中对文档的表示是通过关键字形式描述的,每一个文档可以表示为这样的一个集合
其中 ::=< 单词或短语名称 >< 单词或短语的权值 >
---- 实际上就是采用矢量空间的表示方法来表示的文档。
---- 我们对用户输入的查询表达式也采用矢量空间的表示方法。我们认为用户输入的关键字的顺序代表了它的重要性的程度,所以对于位置靠前的单词有相对比较高的优先级,同时我们对所有的内容以短语或者是单词为最小原子,进行Stem操作,即象前面所提到的:比如单词Encouraging就转化成Encourage的格式。然后去掉那些Stop Word,比如is ,as等等的单词,这些单词存放在StopWordTbl表中。 然后把所有归整化后的内容放入动态数组word_weight_col中去。
---- 2.对于动态数组word_weight_col中的每一个元素,即结构word_weight_pair(包括单词和该单词的权重),我们从表WordDictionaryTbl中可以找到和这些单词相关的记录,这些记录应该是包括了所有的在word_weight_col中的单词。
---- 进行网页是否和查询相匹配的计算。匹配计算的过程如下:首先我们对所有的记录按URL地址进行排序。因为可能好几条记录对应的是一个URL,然后对每一个网页进行打分,每一条记录的单词权值为INITSCORE*WEIGHT+(TOTALTIMES-1)*WEIGHT* INCREMENT。其中INITSCORE为每一个单词的基准分数,TOTALTIMES为该单词在网页中的出现的次数,WEIGHT是该单词在不同的内容段出现有不同的权值(比如在KEYWORD段,或者是标题段,或者是内容段等等)。INCREMENT是该单词每多出现一次所增加的分数。
---- 3.根据用户指定的m_maxReturnSum,显示匹配程度最高的前m_maxReturnSum页。
---- 四、结束语
---- 我们利用上面所讨论的机制,在WINDOWS NT操作系统下,用VC++和SQL SERVER实现了一个Web搜索引擎的网页搜集过程。在建立了一个基本的搜索引擎的框架以后,我们可以基于这个框架,实现一些我们自己设计的算法,比如如何更好的进行Spider的调度,如何更好的进行文档的归类,如何更好的理解用户的查询,用来使Web搜索引擎具有更好的智能性和个性化的特点。
---- 随着Internet的飞速发展,人们越来越依靠网络来查找他们所需要的信息,但是,由于网上的信息源多不胜数,也就是我们经常所说的"Rich Data, Poor Information"。所以如何有效的去发现我们所需要的信息,就成了一个很关键的问题。为了解决这个问题,搜索引擎就随之诞生。
---- 现在在网上的搜索引擎也已经有很多,比较著名的有AltaVista, Yahoo, InfoSeek, Metacrawler, SavvySearch等等。国内也建立了很多的搜索引擎,比如:搜狐、新浪、北极星等等,当然由于它们建立的时间不长,在信息搜索的取全率和取准率上都有待于改进和提高。
---- Alta Vista是一个速度很快的搜索引擎,由于它强大的硬件配置,使它能够做及其复杂的查询。它主要是基于关键字进行查询,它漫游的领域有Web和Usenet。支持布尔查询的"AND","OR"和"NOT",同时还加上最相近定位"NEAR",允许通配符和"向后"搜索(比如:你可以查找链接到某一页的所有Web站点)。你可以决定是否对搜索的短语加上权值,在文档的什么部位去查找它们。能够进行短语查询而不是简单的单词查询的优点是很明显的,比如,我们想要查找一个短语"to be or not to be",如果只是把它们分解成单词的话,这些单词都是属于Stop Word,这样这个查询就不会有任何结果,但是把它当作一个整体来查询,就很容易返回一些结果,比如关于哈姆雷特或者是莎士比亚等等的信息。系统对查询结果所得到的网页的打分是根据在网页中所包含的你的搜索短语的多少,它们在文档的什么位置以及搜索短语在文档内部之间的距离来决定的。同时可以把得到的搜索结果翻译成其他的语言。
---- Exite是称为具有"智能"的搜索引擎,因为它建立了一个基于概念的索引。当然,它所谓的"智能"是基于对概率统计的灵活应用。它能够同时进行基于概念和关键字的索引。它能够索引Web,Usenet和分类的广告。支持"AND","OR","NOT"等布尔操作,同时也可以使用符号"+"和"-"。缺点是在返回的查询结果中没有指定网页的尺寸和格式。
---- InfoSeek是一个简单但是功能强大的索引,它的一个优点是有一个面向主题搜索的可扩展的分类。你可以把你的搜索短语和相似的分类目录的主题短语相互参照,而那些主题短语会自动加到你的查询中去。使你的搜索有更好的主题相关性。同时它也支持对图象的查询。它能够漫游Web,Usenet,Usenet FAQs等等。不支持布尔操作,但是可以使用符号"+"和"-"(相当于"AND"和"NOT")
---- Yahoo实际上不能称为是一个搜索引擎站点,但是它提供了一个分层的主题索引,使你能够从一个通常的主题进入到一个特定的主题,Yahoo对Web进行了有效的组织和分类。比如你想要建立一个网页,但是你不知道如何操作,为了在Yahoo上找到关于建立网页的信息,你可以先在Yahoo上选择一个主题:计算机和Internet,然后在这个主题下,你可以发现一些子主题,比如:Web网页制作,CGI编程,JAVA,HTML,网页设计等,选择一个和你要找的相关的子主题,最终你就可以得到和该子主题相关的所有的网页的链接。也就是说,如果你对要查找的内容属于哪个主题十分清楚的话,通过目录查询的方法要比一般的使用搜索引擎有更好的准确率。你可以搜索Yahoo的索引,但是事实上,你并没有在搜索整个Web。但是Yahoo提供了选项使你可以同时搜索其他的搜索引擎,比如:Alta Vista。但是要注意的是Yahoo实际上只是对Web的一小部分进行了分类和组织,而且它的实效性也不是很好。
---- 搜索引擎的基本原理是通过网络机器人定期在web网页上爬行,然后发现新的网页,把它们取回来放到本地的数据库中,用户的查询请求可以通过查询本地的数据库来得到。如yahoo每天会找到大约500万个新的网页。
---- 搜索引擎的实现机制一般有两种,一种是通过手工方式对网页进行索引,比如yahoo的网页是通过手工分类的方式实现的,它的缺点是Web的覆盖率比较低,同时不能保证最新的信息。查询匹配是通过用户写入的关键字和网页的描述和标题来进行匹配,而不是通过全文的匹配进行的。第二种是对网页进行自动的索引,象AltaVista则是完全通过自动索引实现的。这种能实现自动的文档分类,实际上采用了信息提取的技术。但是在分类准确性上可能不如手工分类。
---- 搜索引擎一般都有一个Robot定期的访问一些站点,来检查这些站点的变化,同时查找新的站点。一般站点有一个robot.txt文件用来说明服务器不希望Robot访问的区域,Robot 都必须遵守这个规定。如果是自动索引的话,Robot在得到页面以后,需要对该页面根据其内容进行索引,根据它的关键字的情况把它归到某一类中。页面的信息是通过元数据的形式保存的,典型的元数据包括标题、IP地址、一个该页面的简要的介绍,关键字或者是索引短语、文件的大小和最后的更新的日期。尽管元数据有一定的标准,但是很多站点都采用自己的模板。文档提取机制和索引策略对Web搜索引擎的有效性有很大的关系。高级的搜索选项一般包括:布尔方法或者是短语匹配和自然语言处理。一个查询所产生的结果按照提取机制被分成不同的等级提交给用户。最相关的放在最前面。每一个提取出来的文档的元数据被显示给用户。同时包括该文档所在的URL地址。
---- 另外有一些关于某一个主题的专门的引擎,它们只对某一个主题的内容进行搜索和处理,这样信息的取全率和精度相对就比较高。
---- 同时,有一类搜索引擎,它本身不用Robot去定期的采集网页。象SavvySearch 和 MetaCrawler是通过向多个搜索引擎同时发出询问并对结果进行综合返回给用户实现搜索功能。当然实际上象SavvySearch能够对各个搜索引擎的功能进行分析和比较,根据不同的用户查询提交给不同的搜索引擎进行处理,当然用户自己也可以指定利用哪一个搜索引擎。
---- 一个优秀的搜索引擎必须处理以下几个问题:1 网页的分类2 自然语言的处理3 搜索策略的调度和协作 4 面向特定用户的搜索。所以很多搜索引擎不同程度的使用了一些人工智能的技术来解决这些方面的问题。
---- 二、网络Spider的实现描述
---- 现在有很多文章对Web引擎做了大量的介绍和分析,但是很少有对它们的实现做一个详细的描述,这里我们主要来介绍一个具有基本功能的Web引擎的实现。本文,我们以类C++语言的形式来描述Web引擎如何采集网页并存放到数据库中的过程。同时描述了如何根据用户输入的关键字查询数据库并得到相关网页的过程。
---- 2.1数据库结构
---- 首先,我们要建立一个数据库表用来存放我们得到的网页。这里一般需要建立如下的表:
---- 1.字典表的建立,事实上这里是用文档中有意义的单词和它们的出现频率来代表一个文档。
---- 该表(WordDictionaryTbl)主要要包括三个字段,主要是用来存放和一个网页相关的单词的情况
url_id 对每一个URL的唯一的ID号
word 该URL中的经过stem的单词
intag 该单词在该网页中的出现的次数
---- 2.存储每一个URL信息的表
---- 该表(URLTbl)中主要的关键字段有:
rec_id 每一条记录的唯一的ID号
status 得到该URL内容的状态,比如HTTP_STATUS_TIMEOUT表示
下载网页的最大允许超时
url URL的字符串名称
content_type 内容的类型
last_modified 最新的更改时间
title 该URL的标题
docsize 该URL的文件的尺寸
last_index_time 最近一次索引的时间
next_index_time 下一次索引的时间
tag 对于网页,用来表示它的类型,比如:是text,或者是html,
或者是图片等等
hops 得到文件时候的曾经失败的次数
keywords 对于网页,和该网页相关的关键字
description 对于网页,指网页的内容的描述
lang 文档所使用的语言
---- 3.因为网页中有很多单词是一些介词和语气助词或者是非常常用的常用词,它们本身没有多少意义。比如:英语中的about,in,at,we,this等等。中文中的如"和","一起","关于"等等。我们统一的把它们称为停止词(stop word)。所以我们要建立一个表,来包括所有这些停止词。该表(StopWordTbl)主要有两个字段。
word char(32) 表示那些停止词
lang char(2) 表示所使用的语言
---- 4.我们要建立一个关于robot的表,我们在前面说过,所有的网站一般都有一个robot.txt文件用来表示网络上的robot可以访问的权限。该表(RobotTbl)主要有以下字段。
hostinfo Web站点主机的信息
path 不允许robot访问的目录
---- 5.建立我们需要屏蔽的那些网页(比如一些内容不健康的或者没有必要去搜索的站点)的一张表(ForbiddenWWWTbl),主要的字段就是网页的URL。
---- 6.另外我们需要建立一个我们所要得到的文件类型的表(FileTypeTbl),比如,对于一个简单的Web搜索引擎,我们可能只需要得到后缀为.html,htm,.shtml和txt的类型文件。其他的我们只是简单的忽略它们。主要的字段就是文件的类型和说明。
---- 其中关于停止词的表的内容是我们要实现要根据各种语言的统计结果,把那些意义不大的单词放进去。关于文档单词、URL和Robot的表的内容都是在获取Web网页的时候动态增加记录的。
---- 2.2 具体网页获取算法描述
---- 具体的网页的获取步骤是这样的:
---- 我们可以设定我们的搜索程序最大可以开的线程的数目,然后这些线程可以同时在网上进行搜索,它们根据数据库中已有的关于网页的信息,找出那些需要更新的网页(如何判断哪些网页需要更新是一个值得研究的过程,现在有很多启发式和智能的算法,基本上是基于统计规律进行建模。最简单的当然是设定一个时间范围,在某个时间范围以前的网页被重新去搜索一遍),然后判断那些网页是否在屏蔽表中,如果是的话,就从关于URL的表中删除该条记录。否则,我们就到相应的WWW站点去得到URL指定的文件(这里需要注意的是根据不同的URL的特点,需要使用不同的协议,比如对于FTP站点要采用FTP协议,对于HTTP站点要采用HTTP协议,新闻站点要采用NNTP协议等等)事实上,我们先得到关于该网页的头信息,如果该网页的最新修改时间和我们最近提取的时间是一样的话,表示该网页内容没有任何更新,则我们就不必去得到它的内容,只需要修改最近一次更新它的时间为当前的时间就可以了。如果该网页最近做了修改,我们就要得到该网页,并对它的内容进行分析,主要要包括和它相关的链接,把它们加到相应的数据库中,同时判断网页所包含的各种其他的文件,如文本文件、图形文件、声音文件和其他多媒体文件是否是我们所需要的文件,如果是的话,就把它加到我们响应的数据库中。同时要根据网页的内容提取所有的有意义的单词和它们的出现的次数,放到相应的数据库中。为了更好的描述这个过程,我们来看跟这个过程相关的主要的几个对象和数据结构。对象主要是针对三个层次来讲的。第一层是针对WWW服务器,第二层是针对每一个页面,第三层是针对每一个页面的全文的索引。
---- 2.3 和实现相关的主要类对象和功能描述下面的结构是针对一个站点来说的。
Class CServer {
主要的属性有:
char *url; //WWW站点的URL名称
char *proxy; //使用的代理的名称
char *basic_auth; //进行基本的HTTP认证
int proxy_port; //代理的端口号
int period; //再次索引的周期
int net_errors; //网络连接不通的次数
int max_net_errors; //可以允许的最大的网络错误
int read_timeout; //下载文件允许的最大的延迟
int maxhops; //表示URL可以最大跳转的深度
int userobots; //是否遵守robot.txt中的约定
int bodyweight; // 在< body >....< /body >之间的单词的权重
int titleweight; // 在< title >....< /title >之间的单词的权重
int urlweight; // 在文档的URL中的单词的权重
int descweight;//在 < META
NAME="Description" Content="..." >之间单词的权重
int keywordweight; //在< META NAME="Keywords" Content="..." >
之间的单词的权重
---- 主要方法有:
FindServer();//用来查找该服务器是否存在并可以连接
FillDefaultAttribute() //用来针对所有的WWW服务器填写默认的属};
以上的对象中的成员变量是和一个站点相关的参数的设置,我们对所有的站点有一个默认的设置,但是可以对某些站点做一些特殊的设置。这些设置可以在配置文件中设定。
---- 下面是关于文档的结构的主要的数据成员:
Class CNetDocument
主要属性有:
int url_id; //该URL的ID号
int status; //获取该文档时候的状态
int size; //文档的尺寸
int tag; //和该文档相关的标签,表示该文档是
HTML,TEXT或者是其他类型
int hops; //URL跳转的次数
char *url; //和该文档相关的URL的名称
char *content_type; //该内容的类型
char *last_modified; //最近一次的更新时间
char *title; //该文档的标题
char *last_index_time; //上次索引的时间
char *next_index_time; //下次索引的时间
char *keywords; //该文档中的关键字
char *description; //该文档的描述
主要方法有:
FillDocInfo(…) //根据数据库,得到该文档相关信息
AddHerf(…) //加入网页中存在的新的链接的网址
DeleteURL(…) //删除一个存在的网址
CanGetThisURL(…) //根据配置决定是否去得到该网页
//下面三个方法是根据不同的URL,用不同的协议去获得文档
NNTPGet(…)
FTPGet(….)
HTTPGet(….)
ParseHead(…) //如果是HTTP协议得到的话,分析头信息
ParseMainBody(…) //对获得的文档的主体进行分析
ServerResponseType (….) //得到服务器端的响应消息
UpdateURLDB(….) //更新的数据入库
} ;
---- 事实上,我们在要提取一个网页的时候,都要建立一个CNetDocument对象,然后再对这个网页进行分析的时候,把相关的内容放到这个CNetDocument的成员变量里面。下面是关于页面全文索引的结构的主要数据成员:
Class CIndexer {
主要属性有:
char *url; //我们要处理的文档相关的URL的名称
int mwords; // 我们事先设定的一个网页的最大的单词数目
int nwords; // 实际的得到的单词的数目
int swords; // 我们已经排序的单词的数目
WORD *Word; //所有单词的内容
char *buf; //我们为文档所分配的空间
主要方法有:
InitIndexer(…) //进行初始设置和分配
ParseGetFile(…) //对得到的网页进行全文索引
AddWord(…) //把网页的可以索引的单词加到Word数组中去
InToDB(….) //关于网页全文索引的信息入库
};
---- 进行网页提取前,我们要建立一个CIndexer对象,它主要是用来对网页进行全文的索引。一般来说我们只对两种类型的URL进行全文索引,一个是text/html,另外一个是text/plain。其中WORD的数据结构如下:
typedef struct word_struct {
int count; //该单词出现的次数
int code; //该单词的正常的形式,
比如单词可能为 encouraging,它的正常的形式应该为
encourage,这其实是一种对单词的stem。
即我们只取单词的主干部分。
char *word; //该单词的内容
} WORD;
---- 以下的结构是和网页中的一些链接的对象相关的一个数据结构
typedef struct href_struct {
char *href; //该链接的名称
int hops; //发生的跳转次数
int stored; //是否已经存储到数据库中
} HREF;
---- 所有需要更新的和新产生的URL都被放到这个结构中,当它的数量超过一定的范围以后,被一次性的存入数据库。
---- 关于URL的一个数据结构如下:
typedef struct url {
char *schema; //表示该URL是通过什么协议得到的,比如HTTP,
FTP,NNTP等。
char *specific; //主机的名称加上路径
char *hostinfo; //主机的名称加上相关的协议端口
char *hostname; //主机的名称
char *path; //在主机的具体的路径
char *filename; //文件的名称
char *anchor; //相关的anchor
int port; //协议相关的端口
} URL;
---- 这是针对URL的一些相关的属性的描述的一个数据结构。事实上在数据库中,我们存储的只是对网页的描述和对一些文本和HTML页面的关键词的索引信息。我们并不存储网页的实际的内容。
---- 三、用户查询实现描述
---- 关于对用户提交的查询请求的实现分析:
---- 用户想要查询某一方面的信息一般都是通过提供和该领域相关的几个关键字来进行的。
---- 我们来看一下关于用户查询的相关的数据结构和类:
---- 下面是一个关于单词和它的权值的基本结构:
typedef struct word_weight_pair
{
char word[WORD_LEN];
int weight;
}word_weight_pair;
---- 下面的类主要是用来对用户的查询进行处理和分析:
Class CUserQuery
{
char m_UserQuery[MAX_QUERYLEN]; //用户的查询表达式
CPtrArray word_weight_col;
//是关于结构word_weight_pair的动态数组
int m_maxReturnSum; //用户希望返回的最多的网页数
int search_mode;
CObArray m_returnDoc; //是关于CNetDocument对象的一个动态数组
NormalizeWord(char* OneWord); //对单词进行归整化,即Stem.
Find(char* odbcName); //进行数据库查找和匹配
};
---- 系统实现的基本的步骤如下:
---- 1.对用户输入的查询表达式进行分析。事实上,我们在前面的Spider搜索过程中对文档的表示是通过关键字形式描述的,每一个文档可以表示为这样的一个集合
其中 ::=< 单词或短语名称 >< 单词或短语的权值 >
---- 实际上就是采用矢量空间的表示方法来表示的文档。
---- 我们对用户输入的查询表达式也采用矢量空间的表示方法。我们认为用户输入的关键字的顺序代表了它的重要性的程度,所以对于位置靠前的单词有相对比较高的优先级,同时我们对所有的内容以短语或者是单词为最小原子,进行Stem操作,即象前面所提到的:比如单词Encouraging就转化成Encourage的格式。然后去掉那些Stop Word,比如is ,as等等的单词,这些单词存放在StopWordTbl表中。 然后把所有归整化后的内容放入动态数组word_weight_col中去。
---- 2.对于动态数组word_weight_col中的每一个元素,即结构word_weight_pair(包括单词和该单词的权重),我们从表WordDictionaryTbl中可以找到和这些单词相关的记录,这些记录应该是包括了所有的在word_weight_col中的单词。
---- 进行网页是否和查询相匹配的计算。匹配计算的过程如下:首先我们对所有的记录按URL地址进行排序。因为可能好几条记录对应的是一个URL,然后对每一个网页进行打分,每一条记录的单词权值为INITSCORE*WEIGHT+(TOTALTIMES-1)*WEIGHT* INCREMENT。其中INITSCORE为每一个单词的基准分数,TOTALTIMES为该单词在网页中的出现的次数,WEIGHT是该单词在不同的内容段出现有不同的权值(比如在KEYWORD段,或者是标题段,或者是内容段等等)。INCREMENT是该单词每多出现一次所增加的分数。
---- 3.根据用户指定的m_maxReturnSum,显示匹配程度最高的前m_maxReturnSum页。
---- 四、结束语
---- 我们利用上面所讨论的机制,在WINDOWS NT操作系统下,用VC++和SQL SERVER实现了一个Web搜索引擎的网页搜集过程。在建立了一个基本的搜索引擎的框架以后,我们可以基于这个框架,实现一些我们自己设计的算法,比如如何更好的进行Spider的调度,如何更好的进行文档的归类,如何更好的理解用户的查询,用来使Web搜索引擎具有更好的智能性和个性化的特点。
发表评论
-
java.lang.NoClassDefFoundError: org/apache/lucene/index/memory/MemoryIndex
2011-06-26 16:37 1893Lucence3.0搜索框架异常: root caus ... -
lucene3.0 中文分词实例IKAnalyzer StandardAnalyzer
2011-04-08 11:11 2425之前想做lucene的中文分 ... -
java匹配中文的正则表达式
2011-01-25 13:46 8187Java的正则表达式如何匹配中文字符呢? 下面给出例子 ... -
htmlparser自定义标签UlTag
2011-01-24 20:05 848htmlparser如何自定义UlTag标签: 代码如 ... -
robots.txt文件解读
2011-01-21 11:02 631robots.txt 搜索引擎搜 ... -
Nutch1.0或者Nutch1.1如何导入MyEclipse与Eclipse?
2011-01-21 09:54 1353Nutch1.0或者Nutch1.1如何导入MyEclipse ... -
java.lang.UnsupportedClassVersionError: Bad version number in .class file
2011-01-20 14:24 688在Eclipse中运行Nutch1.1异常: java.la ... -
Nutch1.1的安装与运行
2011-01-17 11:14 13551 Nutch1.1安装与配置: 1.1 最新版Nutch1. ... -
Nutch-1.1异常信息:No agents listed in 'http.agent.name' property
2011-01-13 15:54 1965Nutch1.1异常信息如下: Fetcher: No a ... -
Cygwin的安装--Nutch搜索引擎环境
2011-01-13 10:40 1519以前想学习Nutcj搜索引擎的时候,总是被如何安装Cygwi ... -
中文字符集与字符编码的基础知识[转载]
2010-10-10 21:09 582中文字符集与字符编 ... -
国内外网站字符编码详解
2010-10-09 10:07 823Utf-8编码在国外应用普遍,为什么在国内应用却不多呢? 尤其 ... -
搜索引擎基本工作原理
2009-05-31 16:06 956今天刚好要了解搜索引 ...
相关推荐
java毕业设计——搜索引擎的设计与实现(论文+答辩PPT+源代码+数据库).zip java毕业设计——搜索引擎的设计与实现(论文+答辩PPT+源代码+数据库).zip java毕业设计——搜索引擎的设计与实现(论文+答辩PPT+源代码+...
数据库设计对于搜索引擎的性能至关重要。为了支持大规模的搜索请求,搜索引擎往往采用分布式数据库架构,如Google的BigTable或Facebook的Cassandra。这些数据库系统能够处理PB级别的数据,并提供高并发读写能力。...
四、 数据库设计 12 4.1数据库的概念设计 12 4.2数据库的逻辑设计 12 五、系统的实现 14 5.1搜索引擎首页界面 14 5.2注册页面实现 14 5.3最新资讯的实现 14 5.4牛闻牛评界面实现 15 5.5搜索功能的实现 15 六、测试 ...
搜索引擎的设计与实现(源码+数据库sql+lun文+视频齐全)搜索引擎的设计与实现(源码+数据库sql+lun文+视频齐全)搜索引擎的设计与实现(源码+数据库sql+lun文+视频齐全)搜索引擎的设计与实现(源码+数据库sql+lun文+视频...
经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件搜索,格式包括txt、doc、xls和ppt; (2)支持分词查询 (3)支持全文搜索 (4)能够高亮...
搜索引擎的设计与实现(源码+数据库sql+论文+视频齐全)【JAVA】.zip 搜索引擎的设计与实现(源码+数据库sql+论文+视频齐全)【JAVA】.zip 搜索引擎的设计与实现(源码+数据库sql+论文+视频齐全)【JAVA】.zip 搜索引擎的...
《搜索引擎的设计与实现》这篇毕业论文是基于Java技术栈,结合Struts、Hibernate和Spring框架进行开发的。这个项目不仅理论研究深入,还包含了实际可运行的代码,为读者提供了全面理解搜索引擎工作原理和实现方法的...
本文中的关键知识点包括搜索引擎的系统结构、网络蜘蛛的工作原理、索引引擎的工作原理、搜索策略、JAVA的应用、搜索引擎的设计与实现、数据库技术、网络爬虫技术和Web服务器技术等。这些知识点对于了解搜索引擎的...
软件工程、计算机专业搜索引擎的设计与实现(源码+数据库sql+视频齐全) 搜索引擎的设计与实现: 经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面...
新闻搜索引擎是从指定的Web页面中按照超连接进行解析、搜索,并把搜索到的每条新闻进行索引后加入数据库。然后通过Web服务器接受客户端请求后从索引数据库中搜索出所匹配的新闻。 本人在介绍搜索引擎的章节中除了...
基于Java的搜索引擎系统设计与实现(项目报告+开题报告+答辩PPT+源代码+数据库+演示录像).zip 基于Java的搜索引擎系统设计与实现(项目报告+开题报告+答辩PPT+源代码+数据库+演示录像).zip 基于Java的搜索引擎系统设计...
基于python的信息安全领域中语义搜索引擎源码数据库论文是关于信息安全领域中语义搜索引擎的开发和实现,涵盖了开发环境、相关技术、系统分析、数据库设计等方面的知识点。 开发环境和相关技术 开发环境是指开发...
在IT行业中,搜索引擎设计是一项复杂而关键的任务,它涉及到计算机科学的多个领域,如信息检索、数据处理、算法设计以及数据库管理。对于学生而言,尤其是计算机专业的毕业生,掌握搜索引擎的设计与实现是提升技能的...
在这个系统中,数据库设计扮演着核心角色,因为它确保了数据的有效存储、检索和管理。下面我们将深入探讨排课系统设计中的数据库设计及其相关知识点。 首先,排课系统的核心目标是合理分配教师、教室和课程时间,...
总之,"python网络搜索引擎的设计源码数据库演示"项目涵盖了Python网络爬虫技术、HTML解析、Django Web框架的应用、数据库管理以及搜索引擎的基本原理。通过这个项目,学习者不仅可以深入理解搜索引擎的工作机制,还...
4.8搜索引擎的设计与实现(源码+数据库sql+lun文+视频齐全).rar 经过对搜索引擎的研究同时与Lucene自身的特性相结合,搜索引擎的设计与实现需要实现的功能阐述如下: (1)支持桌面文件搜索,格式包括txt、doc、xls...
- **设计思路**:设计一个针对手机产品的垂直搜索引擎,首先要明确目标用户群体的需求,然后选择合适的开源工具和技术栈,如使用Heritrix进行网页抓取、Lucene进行数据索引等。 - **实现步骤**: 1. **网页抓取**:...