跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ 基于 Boost 的正倒排索引搜索引擎数据清洗详解

介绍基于 C++ 和 Boost 库实现搜索引擎数据清洗的流程。主要步骤包括:利用 boost::filesystem 递归遍历目录筛选 .html 文件;解析 HTML 源码,通过字符串查找去除标签提取标题与正文;将本地文件路径转换为在线 URL;最后将清洗后的数据以二进制格式保存。代码中修复了类型转换、赋值运算符及文件模式等常见错误。

性能调优发布于 2026/3/27更新于 2026/9/1069 浏览
C++ 基于 Boost 的正倒排索引搜索引擎数据清洗详解

1. 文件枚举

我们要使用到 boost 里面 filesystem 这个命名空间里面的函数,所以我在这里先给它取个别名。然后我们把 src_path 里面的路径交给 root_path。接着我们判断这个路径是否存在,如果不存在那就直接结束代码。接着我们通过迭代器循环的方式来对 root_path 里面的每一个文件。

第一个 if 用来判断是否是普通文件,第二个 if 来判断文件的扩展名是否为 .html,接着走到最后就书面是扩展名为 .html 的普通文件。然后我们就把它的路径转化为 string 类型。

注意:在这里不可以把 .string() 换成 to_string()。这是因为:

.string() 是 std::filesystem::path 类的成员函数,专门用于将路径对象转换为 std::string 类型的字符串(返回路径的字符串表示)。to_string() 是 C++ 标准库中的全局函数(或针对基础类型的重载),用于将数值类型(如 int、double 等)转换为字符串,不能直接用于路径对象。

bool EnumFile(const std::string &src_path, std::vector<std::string> *file_list) {
    namespace fs = boost::filesystem;
    fs::path root_path(src_path);
    if (!fs::exists(root_path)) {
        std::cout << src_path << " is not exist" << std::endl;
        return false;
    }
    fs::recursive_directory_iterator end;
    for (fs::recursive_directory_iterator iter(root_path); iter != end; iter++) {
        if (!fs::is_regular_file(*iter)) continue;
        if (iter->path().extension() != ".html") continue;
        file_list->push_back(iter->path().string());
    }
    return true;
}

2. 内容解析

2.1 读取并解析(去标签化)

这个就是去标签化的函数,通过一步步对文件的解析分别提出 title 和 content,然后构建出 url,接下来就是把 doc 里面的内容交给 results。

bool ParseHtml(const std::vector<std::string> &files_list, const std::string &src_path, std::vector<DocInfo_t> *results) {
    for (const std::string &file : files_list) {
        std::string tr;
        if (!ns_util::FileUtil::ReadFile(file, &tr)) continue;
        DocInfo doc;
        if (!ParseTitle(tr, &doc.title)) continue;
        if (!ParseContent(tr, &doc.content)) continue;
        if (!ParseUrl(file, src_path, &doc.url)) continue;
        results->push_back(doc);
    }
    return true;
}
2.2 提取 title

因为网页的标题一般是 <title>XXXXXXXXXXXXXXXXXXX</title>,然后我们实际上只要 XXXXXXXXXXXXXXXXXXXXX 这个部分,所以我们通过找位置的方式来确定实际想要的内容的位置,然后把它全部获取。

static bool ParseTitle(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) return false;
    *title += file.substr(begin, end - begin);
    return true;
}
2.3 提取 content

我们在这里先创建一个 enum 类型的结构体,用来判断是标签还是我们想要的内容。

然后通过迭代器和 switch 判断的方式,来把所有的 <>的部分去掉。如果是在标签内就一直跳过,如果遇到 > 就判断下一个是不是 <,不是的话就代表是我们想要的内容。

static bool ParseContent(std::string &file, std::string *content) {
    typedef enum status {
        LABEL,
        CONTENT
    } judge;
    judge s = LABEL;
    for (char c : file) {
        switch (s) {
            case LABEL:
                if (c == '>') s = CONTENT;
                break;
            case CONTENT:
                if (c == '<') s = LABEL;
                else {
                    if (c == '\n') c = ' ';
                    *content += c;
                }
                break;
            default:
                break;
        }
    }
    return true;
}
2.4 构建 url

用于构建完整 URL 的函数,其作用是将本地文件路径转换为对应的在线 URL 地址。

建立本地文件与在线文档的对应关系。通过将本地文件的相对路径(相对于 src_path)拼接到固定的 URL 头后面,实现从本地文件路径到在线文档 URL 的转换。

static bool ParseUrl(const std::string &file_path, const std::string &src_path, std::string *url) {
    std::string url_head = "https://www.boost.org/doc/libs/1_89_0/doc/html";
    std::string url_tail = file_path.substr(src_path.size());
    *url = url_head + url_tail;
    return true;
}

3. 结果保存

先以二进制的方式打开 output,接着通过迭代器访问 results 的方式把处理完的信息一段一段的放入临时创建的 out_string 里面,接着当收集完一个网页的信息后在放入 output 里面。

最后关闭 out,完成所有的读取。

bool SaveHtml(const std::vector<DocInfo_t> &results, const std::string &output) {
    std::ofstream out(output);
    if (!out.is_open()) {
        std::cout << "open " << output << " failed!" << std::endl;
        return false;
    }
    for (auto &item : results) {
        std::string out_string;
        out_string += item.title;
        out_string += '\3';
        out_string += item.content;
        out_string += '\3';
        out_string += item.url;
        out_string += '\n';
        out.write(out_string.c_str(), out_string.size());
    }
    out.close();
    return true;
}

目录

  1. 1. 文件枚举
  2. 2. 内容解析
  3. 2.1 读取并解析(去标签化)
  4. 2.2 提取 title
  5. 2.3 提取 content
  6. 2.4 构建 url
  7. 3. 结果保存

更多推荐文章

查看全部
  • 双指针算法实战:快乐数与盛最多水的容器
  • Anaconda 安装与 Python 环境配置详解
  • 程序员面试实战:HR 沟通技巧与核心技术考点解析
  • Python 学习路线与核心知识点详解
  • 华为鸿蒙及安卓手机谷歌验证器安装指南与替代方案
  • 第十三届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组题解
  • C++ 缠论插件的实现思路与架构拆解
  • AIGC 时代 Kubernetes 企业级云原生运维实战:智能重构与深度实践
  • 企业微信 Webhook 机器人集成指南
  • 2026 年跨维度 AR 测试工具的技术演进与实战思考
  • DeepSeek R1 在 RK3588 上的 RKLLM 转换与 Web 部署流程
  • Python 回归分析实战:从线性模型到随机森林
  • Openclaw 2026.3.7 Docker 离线部署指南
  • C++ 在线编译与运行平台怎么选
  • Git 初识与安装入门
  • Java 大数据在智能家居能源消耗趋势预测与节能策略优化中的应用
  • OpenClaw 多 Agent 架构对接飞书机器人实战指南
  • Java 实现 MCP 服务:构建 LLM 专属工具库基座
  • 机器人脑部药物递送三大技术路径的可转化性分析研究
  • 模拟算法实战:核心概念与经典案例解析

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online