Boost搜索引擎 网络库与前端(4)

发布于:2025-09-06 ⋅ 阅读:(19) ⋅ 点赞:(0)


前言

  终于到了最后一篇喽,嘻嘻!


一、引入网络库模块

引入cpp-httplib

  下载地址如下,我个人不喜欢新版本
  cpp-httplib 下载地址

  我们将cpp-httplib放到项目中的test目录下,并解压 unzip 好
在这里插入图片描述

  再建立软链接到我们的项目路径下

在这里插入图片描述

cpp-httplib测试

#include "cpp-httplib/httplib.h"    
      
int main()    
{    
    // 创建一个Server对象,本质就是搭建服务端
    httplib::Server svr; 
 
    // 这里注册用于处理 get 请求的函数,当收到对应的 get 请求时(请求hi时),程序会执行对应的函数(也就是lambda表达式)
    svr.Get("/hi", [](const httplib::Request& req, httplib::Response& rsp){ 
            //设置 get "hi" 请求返回的内容   
            rsp.set_content("hello world!", "text/plain; charset=utf-8");                                                                                                            
          });   
           
    // 绑定端口(8080),启动监听(0.0.0.0表示监听任意端口)
    svr.listen("0.0.0.0", 8080);  
  
    return 0;    
}

  相应的,我们更新一下我们的 makefile

# 定义编译器
CXX = g++

# 定义编译器选项
CXXFLAGS = -std=c++11 

# 定义目标程序
PARSER = parser
DEBUG = debug
HTTP_SERVER = http_server

# 定义链接库
PARSER_LIBS = -lboost_system -lboost_filesystem
DEBUG_LIBS = -ljsoncpp
HTTP_SERVER_LIBS = -ljsoncpp -lpthread

# 默认目标
.PHONY: all
all: $(PARSER) $(DEBUG) $(HTTP_SERVER)

# 编译parser 
$(PARSER): parser.cc
	$(CXX) $(CXXFLAGS) -o $@ $< $(PARSER_LIBS)

# 编译debug 
$(DEBUG): debug.cc
	$(CXX) $(CXXFLAGS) -o $@ $< $(DEBUG_LIBS)

# 编译http_server 
$(HTTP_SERVER): http_server.cc
	$(CXX) $(CXXFLAGS) -o $@ $< $(HTTP_SERVER_LIBS)

# 清理生成的文件
.PHONY: clean
clean:
	rm -rf $(PARSER) $(DEBUG) $(HTTP_SERVER)

  编译后,我们直接开始运行这个 http_server

在这里插入图片描述

  访问这个端口后有如下效果

在这里插入图片描述

  问题在于,现在当我们访问服务器的时候,确实这个效果

在这里插入图片描述

  问题在于,像我们访问百度时,www.baidu.com ,百度会给一个首页,所以在我们的项目目录下呢,也需要一个首页,于是我们在本地目录下创建了一下这个 wwwroot 目录,在该目录下创建了一个 index.html 文件

在这里插入图片描述

正式编写http_server

  好了,测试结束,我们差不多大概也了解了 cpphttplib 的用法

#include "cpp-httplib/httplib.h"
#include "searcher.hpp"

const std::string input = "data/raw_html/raw.txt";
const std::string root_path = "./wwwroot";

int main()
{
    ns_searcher::Searcher search;
    search.InitSearcher(input);

    // 创建一个Server对象,本质就是搭建服务端
    httplib::Server svr;

    // 访问首页
    svr.set_base_dir(root_path.c_str());

    // 这里注册用于处理 get 请求的函数,当收到对应的get请求时(请求s时),程序会执行对应的函数(也就是lambda表达式)
    svr.Get("/s", [&search](const httplib::Request &req, httplib::Response &rsp)
            {
            //has_param:这个函数用来检测用户的请求中是否有搜索关键字,参数中的word就是给用户关键字取的名字(类似word=split)    
            if(!req.has_param("word")){    
                rsp.set_content("必须要有搜索关键字!", "text/plain; charset=utf-8");    
                return;    
            }    
 
            // 获取用户输入的关键字
            std::string word = req.get_param_value("word");    
            std::cout << "用户在搜索:" << word << std::endl;    
            
            // 根据关键字,构建json串
            std::string json_string;    
            search.Search(word, &json_string);
 
            // 设置 get "s" 请求返回的内容,返回的是根据关键字,构建json串内容
            rsp.set_content(json_string, "application/json"); });

    std::cout << "服务器启动成功......" << std::endl;

    // 绑定端口(8080),启动监听(0.0.0.0表示监听任意端口)
    svr.listen("0.0.0.0", 8080);
    return 0;
}

  此时我直接开始 make 编译代码,先执行 parser 进行数据清洗,然后执行 http_server ,搭建服务,创建单例,构建索引,发生请求(根据用户输入的关键字,进行查找索引,构建 json 串),最后响应给我们用户

在这里插入图片描述

  索引建立成功,服务器也启动成功,这个时候进行浏览器访问 (8080/s)

在这里插入图片描述

  访问(8080/s?word=split),结果如下

在这里插入图片描述

  到这里差不多我们的后端部分也就完成了

二、前端模块

  其实我前端不怎么会,以下代码几乎都是参考的 DeepSeek,不得不说 AI 还是强大

  以下给出 DS大人 的前端代码

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <title>Boost 智能搜索引擎</title>
    <style>
        :root {
            --primary-color: #4e6ef2;
            --hover-color: #3b5bdb;
            --background: #f8f9fa;
            --text-dark: #2d3436;
            --text-light: #636e72;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', system-ui, sans-serif;
        }

        body {
            background: var(--background);
            min-height: 100vh;
            padding: 2rem 1rem;
        }

        .container {
            max-width: 800px;
            margin: 0 auto;
            animation: fadeIn 0.5s ease;
        }

        .search-box {
            display: flex;
            gap: 10px;
            margin-bottom: 2rem;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            border-radius: 30px;
            background: white;
            padding: 5px;
        }

        .search-input {
            flex: 1;
            padding: 1rem 1.5rem;
            border: none;
            border-radius: 30px;
            font-size: 1.1rem;
            color: var(--text-dark);
            transition: all 0.3s ease;
        }

        .search-input:focus {
            outline: none;
            box-shadow: 0 0 0 3px rgba(78, 110, 242, 0.2);
        }

        .search-btn {
            padding: 0 2rem;
            border: none;
            border-radius: 30px;
            background: linear-gradient(135deg, var(--primary-color), var(--hover-color));
            color: white;
            font-size: 1rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .search-btn:hover {
            background: var(--hover-color);
            transform: translateY(-1px);
        }

        .result-item {
            background: white;
            border-radius: 12px;
            padding: 1.5rem;
            margin-bottom: 1rem;
            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
            transition: transform 0.2s ease;
        }

        .result-item:hover {
            transform: translateX(5px);
        }

        .result-title {
            color: var(--primary-color);
            font-size: 1.2rem;
            font-weight: 600;
            margin-bottom: 0.5rem;
            text-decoration: none;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .result-title:hover {
            text-decoration: underline;
        }

        .result-desc {
            color: var(--text-dark);
            line-height: 1.6;
            margin-bottom: 0.5rem;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }

        .result-url {
            color: var(--text-light);
            font-size: 0.9rem;
            font-family: monospace;
        }

        .loading {
            text-align: center;
            padding: 2rem;
            color: var(--text-light);
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(20px);
            }

            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        @media (max-width: 768px) {
            .search-box {
                flex-direction: column;
                border-radius: 15px;
            }

            .search-btn {
                padding: 1rem;
                justify-content: center;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="search-box">
            <input type="text" class="search-input" placeholder="请输入搜索关键词..." autofocus>
            <button class="search-btn" onclick="search()">
                <i class="fas fa-search"></i>
                搜索
            </button>
        </div>
        <div class="result-container"></div>
    </div>

    <script>
        // 增强功能
        $(document).ready(() => {
            // 回车键搜索
            $('.search-input').keypress(e => e.which === 13 && search())

            // 输入框交互
            $('.search-input').focus(function () {
                if (this.value === "请输入搜索关键词...") this.value = ""
            }).blur(function () {
                if (this.value === "") this.value = "请输入搜索关键词..."
            })
        })

        function search() {
            const query = $('.search-input').val().trim()
            if (!query) return

            // 显示加载状态
            $('.result-container').html(`
                <div class="loading">
                    <i class="fas fa-spinner fa-spin"></i>
                    正在搜索中...
                </div>
            `)

            $.ajax({
                url: `/s?word=${encodeURIComponent(query)}`,
                method: 'GET',
                success: buildResults,
                error: () => {
                    $('.result-container').html(`
                        <div class="result-item" style="color: #dc3545;">
                            <i class="fas fa-exclamation-triangle"></i>
                            请求失败,请稍后重试
                        </div>
                    `)
                }
            })
        }

        function buildResults(data) {
            const container = $('.result-container').empty()

            if (data.length === 0) {
                container.html(`
                    <div class="result-item">
                        <div style="color: var(--text-light); text-align: center;">
                            <i class="fas fa-search-minus"></i>
                            没有找到相关结果
                        </div>
                    </div>
                `)
                return
            }

            data.forEach(item => {
                const elem = $(`
                    <div class="result-item">
                        <a href="${item.url}" class="result-title" target="_blank">
                            <i class="fas fa-link"></i>
                            ${item.title}
                        </a>
                        <p class="result-desc">${item.desc}</p>
                        <div class="result-url">${item.url}</div>
                    </div>
                `)
                container.append(elem)
            })
        }
    </script>
</body>

</html>

  再次编译运行后,我们来看看效果,不得不感概nb,这要是以我目前的前端水平,完全设计不出来

在这里插入图片描述

三、项目的可能拓展

  这个时候,发挥我们的脑袋,可以看看我们到底有什么可以拓展发挥的地方

  1. 建立整站搜索

  2. 不使用组件,而是自己设计一下对应的各种方案

  3. 在我们的搜索引擎中,添加竞价排名

  4. 热次统计,智能显示搜索关键词(字典树,优先级队列)

  5. 设置登陆注册,引入对 mysql 的使用

  等等都是可以考虑的地方


总结

  结束喽,其实我这个项目包括上一个都是比较简单的,怎么说呢,刚入门,害,加油吧!


网站公告

今日签到

点亮在社区的每一天
去签到