目录

  • 1. 项目的相关背景与目标
  • 2.相关宏观原理
  • 3.技术栈和项目环境
  • 4. 正排索引、倒排索引
  • 5. 数据去标签与数据清洗 Parser
    • 5.1下载文件&&准备工作
    • 5.2编写parser解析文档
      • 5.2.1整体架构
      • 5.2.2EnumFile
      • 5.2.3ParseHtml
        • 5.2.3.1框架
        • 5.2.3.2ns_util::FileUtil::ReadFile(); 读取文件
        • 5.2.3.3ParseTitle();提取标签
        • 5.2.3.4ParseContent();获取文档的Content(解析去标签)
        • 5.2.3.5 ParseUrl();
        • 5.2.3.6测试
    • 5.3SaveHtml();将解析结果写入到文件当中
    • 5.4锦上添花
    • 5.5结果
  • 6. 建立索引模块 Index
    • 6.1 index.hpp整体框架
    • 6.2GetForwardIndex();GetInvertedList();BuildIndex()框架
      • 6.2.1BuildForwardIndex();构建正排索引
      • 6.2.2BuildInvertedIndex();构建倒排索引
        • 6.2.2.1思路
        • 6.2.2.2 分词工具 cppjieba 介绍:
        • 6.2.2.3将cppjieba 写入util.hpp中
        • 6.2.2.4问题:暂停词
        • 6.2.2.5编写倒排索引的代码
  • 7.搜索引擎模块 Searcher.hpp
    • 7.1整体框架
    • 7.2将Index设置为单例模式
    • 7.3 InitSearcher();
    • 7.4Search();
      • 7.4.1安装josncpp
      • 7.4.2josncpp测试:
      • 7.4.3Search()编写
      • 7.4.4测试
      • 7.4.5建立摘要
      • 7.4.6GetDesc();
      • 7.4.7问题:
        • 7.4.7.1问题介绍:
        • 7.4.7.2问题测试:
        • 7.4.7.3问题解决
  • 8.http_server模块
    • 8.1准备工作,
      • 8.1.1安装较新版本的gcc
      • 8.1.2安装cpp-httplib
      • 8.1.3测试
    • 8.2代码:
  • 9.前端
  • 10.添加日志log.hpp
    • 10.1代码:
    • 10.2测试:
    • 10.3将程序部署到服务器上
  • 11.整体理解
    • 11.1各个文件简介
    • 整体思路
  • 12.个人遇见问题整理
    • 12.1点击链接自动添加ip和端口号
    • 12.2关于12.1的补充
    • 12.3关于网络端口号

1. 项目的相关背景与目标

针对boost网站没有搜索导航功能,为boost网站文档的查找提供搜索功能

站内搜索:搜索的数据更垂直,数据量小
类似于cplusplus.com的搜索

2.相关宏观原理

3.技术栈和项目环境

技术栈:C/C++,C++11,STL,准标准库Boost(相关文件操作),jsoncpp(客户端和数据端数据交互),cppjieba(将搜索关键字进行切分),cpp-httplib(构建http服务器)
其他技术栈(前端):html5,css,js,jQuery,Ajax
项目环境:Centos 7云服务器,vim/gcc(g++)/Makefile,vs2019/vs code(网页)

4. 正排索引、倒排索引

正排索引:从文档ID找到文档内容(文档内的关键字)
正排索引类似于书的目录,我们可以根据页数查找到对应的内容

目标文档进行分词:目的:方便建立倒排索引和查找
停止词:了,吗,的,the,a,一般情况我们在分词的时候可以不考虑

倒排索引:根据文档内容,分词,整理不重复的各个关键字,对应联系到文档ID的方案
文档ID中,各个文档ID的排序按照权重进行排序
倒排索引和正排索引是相反的概念,我们可以根据文档内容查询到这部分内容在哪些文件中出现,从而找到对应的文件

模拟查找过程
用户输入:
关键字->倒排索引中查找->提取出是文档ID(x,y,z,,,)->根据正排索引->找到文档的内容->将文档内容中的title+conent(desc)+url+文档结果进行摘要->构建响应结果

5. 数据去标签与数据清洗 Parser

5.1下载文件&&准备工作

经过测试:
edge,和360浏览器不能下载,每次的速度都是极慢(不到30KB),
并且在下载到一定时间后,会因为权限不足等情况直接不能下载
所以这个下载只能使用chrome下载,
虽然下载的速度还是很慢,但是不会因为其他问题而导致不能下载

下载好之后,
创建目录
然后将文件拖进Linux中
然后解压

我们只需要boost_1_79_0/doc/html/* 内的所有网址即可:

然后删除boost_1_79_0即可:

我们只需要:boost_1_79_0/doc/html 目录下的html文件,用它来进行建立索引


原始数据->去标签之后的数据

查看一共多少html文件

目标:
把每个文档都去标签,然后写入到同一个文件中,每个文档内容只占一行!文档和文档之间‘\3’区分。

为什么是\3?

5.2编写parser解析文档

5.2.1整体架构


#include<iostream>
#include<string>
#include<vector>//目录
const std::string src_path = "data/input/";
const std::string output = "data/raw_html/raw.txt";typedef struct DocInfo
{std::string title;//文档标题    std::string content;//文档内容    std::string url;//该文档在官网中的url
}DocInfo_t;//格式规范:const &:输入;*:输出;&:输入输出
// 运用boost库进行读取
bool EnumFile(const std::string& src_path, std::vector<std::string>* files_list);
//解析标签,
bool ParseHtml(const std::vector<std::string>& files_list, std::vector<DocInfo_t>* results);
//保存文件
bool SaveHtml(const std::vector<DocInfo_t>& results, const std::string& output);int main()
{std::vector<std::string> files_list;//(1)将每个html文件名带路径保存到file_list中if (!EnumFile(src_path, &files_list)){std::cerr << "枚举文件名失败!" << std::endl;return 1;}//(2)对files_list中的每个文件内容进行解析std::vector<DocInfo_t> results;if (!ParseHtml(files_list, &results)){std::cerr << "解析html失败" << std::endl;return 2;}//(3)解析完后,将文件内容写入ouput,用'\3'进行分割if (!SaveHtml(results, output)){std::cerr << "保存文件失败!" << std::endl;return 3;}return 0;
}

5.2.2EnumFile

我们需要使用filesystem函数(boost库中的)

boost库安装

sudo yum install -y boost-devel
//devel是boost开发库

我们用的是1.53,我们搜索的是1.79,这两个不冲突。

boost网页查看函数使用方法:

#include<boost/filesystem.hpp>
bool EnumFile(const std::string& src_path, std::vector<std::string>* files_list)
{namespace fs = boost::filesystem;fs::path root_path(src_path);//遍历时,从这个路径开始    //判断路径是否存在     if (!(fs::exists(root_path))){std::cerr << src_path << "不存在" << std::endl;return false;}//对文件进行递归遍历    //定义一个空的迭代器,用来进行判断递归结束    fs::recursive_directory_iterator end;for (fs::recursive_directory_iterator iter(root_path); iter != end; iter++){//判断文件是否为普通文件(html)都是普通文件    if (!(fs::is_regular_file(*iter)))  continue;//判断文件后缀是否为 .html     //path()迭代器的一种方法,用来提取路径的字符串;extension()提取带路径的文件名后缀    if (iter->path().extension() != ".html") continue;//std::cout<<"插入路径:"<<iter->path().string()<<std::endl;//测试代码,测试其是否能正常插入    //当前的路径一定是一个合法的,以.html结束的普通网页文件                                       //string()可以将其转化为字符串的形式                                                          files_list->push_back(iter->path().string());}return true;
}

5.2.3ParseHtml

5.2.3.1框架

bool ParseHtml(const std::vector<std::string>& files_list, std::vector<DocInfo_t>* results)
{for (const std::string& file : files_list){//1.读取文件 Read()    std::string result;//读取文件放到这里    if (!(ns_util::FileUtil::ReadFile(file, &result))) {continue;//读取失败,继续处理下一个文件    }//2.解析指定文件,提取title    DocInfo_t doc;//解析title    if (!(ParseTitle(result, &doc.title))) {continue;//提取报头失败    }//3.解析指令的文件,提取content(内容)(去标签)    if (!(ParseContent(result, &doc.content))) {continue;}//4.解析指定的文件路径,构建url    if (!(ParseUrl(file,&doc.url))){continue;}//push_back()本质是拷贝,效率低    results->push_back(doc);}return true;
}

5.2.3.2ns_util::FileUtil::ReadFile(); 读取文件

延伸知识点:
如何理解getline读取到文件结束呢?
getline返回的是一个&,
本质是因为重载了强制类型转化

#include<iostream>
#include<string>
#include<fstream>      namespace ns_util
{class FileUtil{public://读取文件      static bool ReadFile(const std::string& file_path, std::string* out){//只读打开      std::ifstream in(file_path, std::ios::in);if (!in.is_open())//打开失败      {std::cerr << "打开失败!" << std::endl;return false;}std::string line;while (std::getline(in, line)){*out += line;}in.close();return true;}};
}

5.2.3.3ParseTitle();提取标签

static bool ParseTitle(const std::string& file, std::string* title)
{std::size_t begin = file.find("<title>");if (begin == std::string::npos)//没有找到    return false;std::size_t end = file.find("</title>");if (end == std::string::npos)//没有找到    return false;begin += std::string("<title>").size();if (begin > end)//判断begin和end位置关系    return false;*title = file.substr(begin, end - begin);return true;
}

5.2.3.4ParseContent();获取文档的Content(解析去标签)

在进行遍历的时候,
只要碰到了 >,就意味着,当前的标签被处理完毕
只要碰到了 <,就意味着,新的标签开始了

static bool ParseContent(const std::string& file, std::string* content)
{//去标签,基于一个简易的状态机enum status {LABLE,CONTEN};enum status s = LABLE;for (char c : file){switch (s){case LABLE:if (c == '>') s = CONTEN;break;case CONTEN:if (c == '<') s = LABLE;else{//我们不想保留原始文件的'\n',因为我们想用'\n'作为html解析文本之后的分隔符if (c == '\n') c = ' ';content->push_back(c);}break;default:break;}}return true;
}

5.2.3.5 ParseUrl();

构建URL
boost库的官方文档,和我们下载下来的文档,是有路径对应关系的

官网URL样例: https

实战项目:Boost搜索引擎相关推荐

  1. C++综合项目-boost搜索引擎

    文章目录 一.项目简介 1.1 项目背景 1.2 相关技术和库 1.2.1 正排索引 1.2.2 倒排索引 1.2.3 相关库 1.3 搜索引擎的原理简述 二. 项目的实现过程 2.1 下载boost ...

  2. 【C++项目】boost搜索引擎项目

    文章目录 项目的gitee地址 项目基本演示 讲解思路 一:项目相关背景 二:搜索引擎的相关宏观原理 三:搜索引擎技术栈和项目环境 四:正排索引 vs 倒排索引 - 搜索引擎具体原理 五:编写数据去标 ...

  3. python爬虫项目-32个Python爬虫实战项目,满足你的项目慌

    原标题:32个Python爬虫实战项目,满足你的项目慌 爬虫项目名称及简介 一些项目名称涉及企业名词,小编用拼写代替 1.[WechatSogou]- weixin公众号爬虫.基于weixin公众号爬 ...

  4. 在线教育数据分析实战项目案例

    数据分析实战项目案例 数据分析概览 数据分析经常遇到的问题 解决思路 常规产品指标 在线教育产品指标 市场效果广告指标 搭建指标系统流程 渠道的分类 针对搜索引擎,信息流广告如何稳定提高ROI 利用M ...

  5. python投票系统项目ppt_python fastApi实战项目 - 爱投票管理系统(一)

    一.闲来无事,在工作之余自己研究了一下python的异步框架 - fastapi,并写包括 1.部门管理 2.角色管理 3.用户管理 4.菜单管理 5.登录日志 6.操作日志 六个基础功能模块,演示链 ...

  6. 10个Python爬虫实战项目

    Python爬虫是指使用Python语言编写程序,自动化地从互联网上获取数据并进行处理和分析的技术.Python爬虫是一项复杂而且实用的技术,需要掌握多个方面的基础知识,并具备较强的编程能力和实际操作 ...

  7. 35个Python实战项目,完整源代码!

    收集整理最新36个python实战项目源代码,系统实用,不是普通的小脚本! 多看多练是提升代码能力的最佳途径,一起操练起来! 视频转字符动画 12306 B站弹幕 B站滑块验证码破解 GUI签名 py ...

  8. 大型电商实战项目,助力2021年高薪

    文章目录 序言 推荐背景 项目介绍 整体架构图形 热点技术栈 项目特点 适合人群 对比番外类似的项目 痛点和选择 序言 2021 新的一年开始,祝愿大家工作顺利,事事顺心.如果你有幸看到这一篇文章,请 ...

  9. Python网络爬虫实战项目代码大全(长期更新,欢迎补充)

    Python网络爬虫实战项目代码大全(长期更新,欢迎补充) 阿橙 · 1 个月内 WechatSogou [1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫, ...

  10. 超硬核Java学习路线图+学习资源+实战项目汇总,看完以后不用再问我怎么学Java了!

    之前写过很多次关于Java学习指南.Java技术路线图的文章.但是总还是有小伙伴来问我,Java怎么学,项目怎么做,资源怎么找,真是让人头秃. 于是这次黄小斜决定来一波狠的,把所有这些内容都整理起来, ...

最新文章

  1. 缓存击穿!竟然不知道怎么写代码???
  2. centos 7 ssh 安装mysql,Centos 7 安装Airflow
  3. I/O模型之一:Unix的五种I/O模型
  4. boost::geometry::coordinate_type用法的测试程序
  5. MySQL之innodb与myisam:锁 事务 外键 主键 存储结构 存储大小 索引 count 注重点
  6. 解锁一个新技巧,让你舒服到不想起床
  7. java数据抽取到数据仓库_关于数据增量抽取的模拟实现——脚本实现
  8. Vs code 02 配置非标准的C、C++的编译环境
  9. 3个最典型的图表错误使用方式,赶紧看看自己是否中招
  10. java前端学习路线_Java前端需要学什么?Java前端学习路线分享
  11. 学习笔记-Bandit-WalkThrough
  12. verilog实现格雷码(Gray Code)与二进制编码转换
  13. 《分布式资本链周刊》第二期
  14. 如何构建你的认知体系?查理芒格的100个思维模型
  15. 定时器+echarts运行时间太长导致内存溢出页面崩溃
  16. redis报错 Error getaddrinfo ENOTFOUND
  17. 亲生骨肉 窥视父母遗产 为了继承遗产竟用这种方式替代...
  18. Windows上python读取grib2文件(不用Linux)
  19. 简易kafka消息服务器搭建
  20. Android 音视频配音之音频提取、截断、混音、合并、合成(二)——将提取的PCM根据时间戳截断

热门文章

  1. 我被一只老鼠的吱吱声吵醒了
  2. 白胡子不杀黑胡子的真正原因
  3. IDR 关键帧 GOP
  4. java 开发平台 普元_普元开发平台好不好?
  5. Codeforces 1077B Disturbed People(思维题)
  6. 【心随意动】20-SIST研一秋季上学期课程总结【补】
  7. 前后端分离与耦合架构
  8. Could Not Autowired ,No Beans of ....
  9. 【个人作品】企业级财务报表可视化——资产负债表
  10. 离散数学——图论中图的同构的应用