【北大天网搜索引擎TSE学习笔记】第4节——实现搜索功能的入口程序

 上一节中说到,TSESearch.cpp是实现搜索功能的入口程序,这一节将分析TSESearch.cpp源代码。在看源代码之前,先梳理一下该程序中的主要步骤:

(1)准备数据

在第二节中介绍了系统中一些重要的数据文件,这些文件便是实现搜索功能所需的数据文件,如:字典文件、倒排文件、网页索引文件和URL索引文件等。程序第一步需要读取这些文件的内容为搜索做好准备。

(2)获取用户输入

获取用户输入的欲查询的搜索字符串,这里需要CGI程序与Web服务器交互,通过环境变量的方式来获取用户输入的字符串。

(3)中文分词

因为用户输入的搜索字符串不是最简的单字或词,有可能是自然语言的句子或者是短语,如:“中国最优秀的程序员”,如果直接在倒排表中寻找这样的字符串,肯定是找不到任何结果的,因为倒排表中的词也是根据词典将网页内容进行分词切割后的最简字或者词。所以需要根据分词算法对输入的原始串进行分词切割,如上面的例子被分割为:“中国 /最 /优秀 / 的/ 程序员/”。

(4)检索关键词

对分割后的独立的关键词分别在倒排表中进行查询,找到关键词出现的网页文件。

(5)结果排序

含有一个或者若干个关键词的网页可能很多,如果仅仅是将他们不做任何处理的呈现给用户,肯定不是最好的。因为不同的网页的质量肯定是不一样的,如果为用户进行筛选,将最好的结果显示在前面,便需要对结果的网页集合进行排序。关于搜索结果的网页的质量计算和排序,可以查找相关的资料学习,如:Google的民主表决式网页排名技术PageRank方法,TF-IDF方法等,这里推荐吴军博士的《数学之美》一书,书中第十章、十一章对这些内容做了很好的讲解。

(6)显示搜索结果

这里需要CGI程序与Web服务器交互,通过标准输出的方式将结果发送到浏览器进行显示。

 

下面来看TSESearch.cpp中的main函数,我在代码中清楚的标注了哪一段代码对应于上面的哪一步骤,同时加入了注释(以“LB_C”开始的注释为我加入的)对重要代码进行了说明。

int main(int argc, char* argv[])
{
   struct timeval begin_tv, end_tv;
   struct timezone tz;
 
   static int nCnt = 0;
   ++nCnt;
 
   //================================ LB_c: 准备数据================================
   //LB_c: 字典对象,定义在./ChSeg/Dict.h中,该类的构造函数中会加载字典字典文件
   // (words.dict)。
   CDict iDict;
 
   //LB_c: mapBuckets为倒排索引表,保存keyword->docid的映射
   map<string, string> dictMap, mapBuckets;
 
   //LB_c: vecDocIdx存储网页索引表,DocIdx类定义在Document.h中,是docid到offset的映射
   //关系.
   vector<DocIdx> vecDocIdx;
   //================================ LB_c: 准备数据 ================================
 
   
   //============================== LB_c: 获取用户输入 ==============================
   //LB_c: 该类为搜索功能的实现类,提供加载数据文件、获取用户输入、中文分词、检索关
   // 键词等接口。
   CQuery iQuery;
 
   //LB_c: 获取用户输入的搜索字符串,利用CGI程序读取环境变量的方法。
   iQuery.GetInputs();
   
   // current query & result page number
   //LB_c: 设置搜索字符串到成员变量m_sQuery
   iQuery.SetQuery();   
 
   //LB_c: 设置显示查询结果的第几页(因为搜索结果可能有很多页,但是一次只能显示一页)
   // 用户提交的URL中有一个名为start的键值对指示显示第几页,如用户在结果页面中手动选
   // 择显示第几页时,或者在结果页面中提交新查询时。但是用户从首页提交搜索时URL中没有
   // start键值,所以这里需要设置一个默认值,这里的SetStart函数有一点点问题,我对其进
   // 行了修改。
   iQuery.SetStart();
   //============================== LB_c: 获取用户输入 ==============================
 
   
   // begin to search
   gettimeofday(&begin_tv,&tz);
 
 
   //================================ LB_c: 准备数据 ================================
   //LB_c: 读取倒排索引文件(./Data/sun.iidx),将keyword->docid的映射存入mapBuckets中
   iQuery.GetInvLists(mapBuckets);
 
   //LB_c: 读取网页索引文件(./Data/Doc.idx),将docid->offset的映射存入vecDocIdx中
   iQuery.GetDocIdx(vecDocIdx);
   //================================ LB_c: 准备数据 ================================
 
 
   //================================ LB_c: 中文分词 ================================
   //LB_c: 中文分词类,定义于HzSeg.h
   CHzSeg iHzSeg;   
   
   //LB_c: 该函数进行中文分词,iDict字典对象。将原字符串中插入"/"进行分割,分割后的
   // 字符串存入m_sSegQuery.
   iQuery.m_sSegQuery = iHzSeg.SegmentSentenceMM(iDict,iQuery.m_sQuery);
   
   //LB_c: 存放分割后的独立的关键词
   vector<string> vecTerm;
   //LB_c: 从分割后的串m_sSegQuery中获取独立的关键词一一存入vector中
   iQuery.ParseQuery(vecTerm);
   //================================ LB_c: 中文分词 ================================
   
 
   //=========================== LB_c: 检索关键词+结果排序==========================
   //LB_c: 存储搜索结果的网页的docid
   set<string> setRelevantRst;
   
   //LB_c: vecTerm中存储的分割后的独立关键词,mapBuckets存储的倒排表,在倒排表中分别
   // 检索verTerm中的所有独立关键词,然后进行简单的结果排序。实际上结果排序非常重要,
   // 要达到很好的效果算法也非常复杂,TSE系统中只是简单的实现了结果排序,所以与关键词
   // 检索在一个函数里实现。
   iQuery.GetRelevantRst(vecTerm, mapBuckets, setRelevantRst);
   //=========================== LB_c: 检索关键词+结果排序==========================
   
 
   gettimeofday(&end_tv,&tz);
    // search end
 
 
   //============================== LB_C: 显示搜索结果 ==============================
   //LB_c: 结果显示类,类中主要有ShowTop,ShowMiddle和ShowBelow三个接口,用标准输出
   // html语句的方式显示结果页面。
   CDisplayRst iDisplayRst;
   
   //LB_c: 显示结果页面的头部
   iDisplayRst.ShowTop();
 
   //LB_c: 计算搜索过程耗费的时间
   float used_msec = (end_tv.tv_sec-begin_tv.tv_sec)*1000
       +((float)(end_tv.tv_usec-begin_tv.tv_usec))/(float)1000;
   
   //LB_c: 显示结果页面的中部,主要是一些结果信息:用户的查询串、耗时、找到的结果页面
   // 总数和分页显示的分页链接等。
   iDisplayRst.ShowMiddle(iQuery.m_sQuery,used_msec,
           setRelevantRst.size(), iQuery.m_iStart);
 
   //LB_c: 显示结果页面的底部,就是搜索的结果,以列表的形式列出。主要包括网页的URL,
   // 网页大小,网页内容的摘要和网页快照的链接等。
   cout << "<p>iQuery.m_iStart : " <<iQuery.m_iStart << "</p>\n";
   iDisplayRst.ShowBelow(vecTerm,setRelevantRst,vecDocIdx,iQuery.m_iStart);
   //============================== LB_C: 显示搜索结果 ==============================
 
   return 0;
}

By:

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TSE(Tiny Search Engine) ======================= (Temporary) Web home: http://162.105.80.44/~yhf/Realcourse/ TSE is free utility for non-interactive download of files from the Web. It supports HTTP. According to query word or url, it retrieve results from crawled pages. It can follow links in HTML pages and create output files in Tianwang (http://e.pku.edu.cn/) format or ISAM format files. Additionally, it provies link structures which can be used to rebuild the web frame. --------------------------- Main functions in the TSE: 1) normal crawling, named SE, e.g: crawling all pages in PKU scope. and retrieve results from crawled pages according to query word or url, 2) crawling images and corresponding pages, named ImgSE. --------------------------- INSTALL: 1) execute "tar xvfz tse.XXX.gz" --------------------------- Before running the program, note Note: The program is default for normal crawling (SE). For ImgSE, you should: 1. change codes with the following requirements, 1) In "Page.cpp" file, find two same functions "CPage::IsFilterLink(string plink)" One is for ImgSE whose urls must include "tupian", "photo", "ttjstk", etc. the other is for normal crawling. For ImgSE, remember to comment the paragraph and choose right "CPage::IsFilterLink(string plink)". For SE, remember to open the paragraph and choose righ "CPage::IsFilterLink(string plink)". 2) In Http.cpp file i. find "if( iPage.m_sContentType.find("image") != string::npos )" Comment the right paragraph. 3) In Crawl.cpp file, i. "if( iPage.m_sContentType != "text/html" Comment the right paragraph. ii. find "if(file_length < 40)" Choose right one line. iii. find "iMD5.GenerateMD5( (unsigned char*)iPage.m_sContent.c_str(), iPage.m_sContent.length() )" Comment the right paragraph. iv. find "if (iUrl.IsImageUrl(strUrl))" Comment the right paragraph. 2.sh Clean; (Note not remove link4History.url, you should commnet "rm -f link4History.url" line first) secondly use "link4History.url" as a seed file. "link4History" is produced while normal crawling (SE). --------------------------- EXECUTION: execute "make clean; sh Clean;make". 1) for normal crawling and retrieving ./Tse -c tse_seed.img According to query word or url, retrieve results from crawled pages ./Tse -s 2) for ImgSE ./Tse -c tse_seed.img After moving Tianwang.raw.* data to secure place, execute ./Tse -c link4History.url --------------------------- Detail functions: 1) suporting multithreads crawling pages 2) persistent HTTP connection 3) DNS cache 4) IP block 5) filter unreachable hosts 6) parsing hyperlinks from crawled pages 7) recursively crawling pages h) Outputing Tianwang format or ISAM format files --------------------------- Files in the package Tse --- Tse execute file tse_unreachHost.list --- unreachable hosts according to PKU IP block tse_seed.pku --- PKU seeds tse_ipblock --- PKU IP block ... Directories in the package hlink,include,lib,stack,uri directories --- Parse links from a page --------------------------- Please report bugs in TSE to MAINTAINERS: YAN Hongfei * Created: YAN Hongfei, Network lab of Peking University. * Created: July 15 2003. version 0.1.1 * # Can crawl web pages with a process * Updated: Aug 20 2003. version 1.0.0 !!!! * # Can crawl web pages with multithreads * Updated: Nov 08 2003. version 1.0.1 * # more classes in the codes * Updated: Nov 16 2003. version 1.1.0 * # integrate a new version linkparser provided by XIE Han * # according to all MD5 values of pages content, * for all the pages not seen before, store a new page * Updated: Nov 21 2003. version 1.1.1 * # record all duplicate urls in terms of content MD5

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值