c 语言打造搜索引擎,GitHub - Worthy-Wang/LightSE: LightSE基于Linux 平台、C/C++语言实现。该项目是一个用于网页查询的轻量级搜索引擎。实现了从爬取网页,处...

项目简介

服务器端基于Linux 平台、C/C++语言;客户端采用PHP 实现;爬虫采用Python 实现。

该项目是一个用于网页查询的轻量级搜索引擎。实现了从爬取网页,处理网页,显示结果等整个搜索引擎的流程。该项目分为三个阶段:线下阶段,线上阶段,优化阶段。线下部分使用tinyxml2解析爬取的网页,以此建立网页库,网页偏移库;再使用cppjieba分词库,TopK算法生成指纹信息作为去重标准并生成新的网页库与网页偏移库,去重后通过TF-IDF算法建立倒排索引库。线上部分则使用EchoLib框架搭建服务器,客户端发送查询词后,服务器计算文本特征并建立VSM模型,并使用余弦相似度算法匹配网页,将匹配的网页通过余弦值排序后使用jsoncpp封装后发送。优化部分则使用mysql作为网页存储的数据库,redis作为Cache缓存,log4cpp添加日志系统。

项目详细流程

该项目主要分为三个阶段:线下阶段,线上阶段,优化阶段。

线下阶段

首先使用tinyxml2解析python爬取的网页,将爬取的网页进行进行解析之后放入内存,再将内存中的网页整理格式之后,输出到磁盘,这也就时创建 网页库 与 网页偏移库 的过程。

读取网页库与网页偏移库,使用 cppjieba库 对文章进行分词,再使用 TopK算法 计算出每一篇文章最高频的k个单词,以这k个单词作为该文章的 指纹信息, 这样可以达到对文章去重的效果。根据去重之后的 文章,建立 新的网页库 与 新的网页偏移库。

使用 TF-IDF 算法建立 倒排索引库。

补充:

TF-IDF算法

该算法实质上是一种计算权值的算法,主要用于计算出每一个词在每一篇文章中所占的权值,也可以理解成某个单词在某个文章中的重要程度。

举例:

有很多不同的数学公式可以用来计算TF-IDF。这边的例子以上述的数学公式来计算。词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个,而词语“母牛”出现了3次,那么“母牛”一词在该文件中的词频就是3/100=0.03。一个计算文件频率 (IDF) 的方法是文件集里包含的文件总数除以测定有多少份文件出现过“母牛”一词。所以,如果“母牛”一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是 lg(10,000,000 / 1,000)=4。最后的TF-IDF的分数为0.03 * 4=0.12。

计算过程较为复杂,详细可参考:

百度百科:TF-IDF算法

倒排索引

倒排索引是通过属性值来查找记录。通常我们使用索引,是通过记录来查找属性,但是这样显然效率太低;于是倒排索引的出现帮助我们解决了效率的问题,因为它可以通过属性值找到对应的记录。

项目中建立的倒排索引:

unordered_map>> _invertIndexTable; //倒排索引 >

线上阶段

采用EchoLib并发服务器框架,此时假设客户端发送查找 如何成为大师级程序员 相关的网页。

服务器的处理流程如下:

将客户端发送的查询语句看成一篇文章,通过TF-IDF算法计算出各个单词在该篇文章中的权重。

通过倒排索引,查找出所有匹配的网页。这里的匹配代表着该网页中包含客户端查询词中的所有关键词。

使用 余弦相似度算法 计算出每一篇网页对应查询语句的余弦相似度,根据余弦相似度大小对网页进行排序。

为每一篇网页都形成摘要。

将文章封装成json字符串返回给客户端。

客户端解析json字符串并显示。

优化阶段

使用mysql数据库来存储网页。

使用redis来作为缓存cache。

log4cpp记录日志文件。

Demo展示

68747470733a2f2f696d672d626c6f672e6373646e696d672e636e2f32303230313130353137343434363436332e676966237069635f63656e746572

同时,在VScode的后台也记录了查询词,并且将其记录到了日志文件中,方便查看。

68747470733a2f2f696d672d626c6f672e6373646e696d672e636e2f3230323031313035313734333431322e706e673f782d6f73732d70726f636573733d696d6167652f77617465726d61726b2c747970655f5a6d46755a33706f5a57356e6147567064476b2c736861646f775f31302c746578745f6148523063484d364c7939696247396e4c6d4e7a5a473475626d56304c316476636e526f655639585957356e2c73697a655f31362c636f6c6f725f4646464646462c745f3730237069635f63656e746572

架构图

5d64968ada18a4c031e4038185c0a7a3.png

技术亮点

离线版本

建立网页库与网页偏移库

技术亮点:开源库tinyxml2(DFS遍历节点), 正则表达式,文件流字符串流操作, Unix目录操作,单例模式(饿汉)

网页去重

技术亮点: 开源库cppjieba分词,set停词集合,TopK算法(判断网页重复)

建立倒排索引

技术亮点:unordered_map倒排哈希表,TF-IDF算法(计算权重)

在线部分

搭建线程池框架

技术亮点:基于对象线程池设计,Posix线程类,互斥锁,条件变量,任务队列,自动加解锁类,子线程安全退出机制,回调函数,智能指针unique_ptr

搭建服务器框架

技术亮点:基于对象服务器设计,回调函数,socket网络编程,IO多路复用epoll,eventfd(IO线程与计算线程分离),客户端安全退出机制 ,智能指针shared_ptr

(前两步框架可直接使用博主的开源项目 MirrorLib)

搭建搜索引擎框架

技术亮点:文件流字符串流操作,TF-IDF算法,开源库log4cpp记录日志,余弦相似度算法,开源库jsoncpp

优化功能

使用mysql作为网页存储的数据库

使用redis作为Cache缓存

算法详解

如果对于上述算法感觉不是很理解,可以看看这一篇文章:

基于 K-means 算法实现的文本聚类(干货)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值