计算机竞赛 python的搜索引擎系统设计与实现

news2024/12/26 20:41:36

0 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 python的搜索引擎系统设计与实现

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:5分
  • 创新点:3分

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate


1 课题简介

随着互联网和宽带上网的普及, 搜索引擎在中国异军突起, 并日益渗透到人们的日常生活中, 在互联网普及之前,
人们查阅资料首先想到的是拥有大量书籍的资料的图书馆。 但是今天很多人都会选择一种更方便、 快捷、 全面、 准确的查阅方式–互联网。
而帮助我们在整个互联网上快速地查找到目标信息的就是越来越被重视的搜索引擎。

今天学长来向大家介绍如何使用python写一个搜索引擎,该项目常用于毕业设计


在这里插入图片描述

2 系统设计实现

2.1 总体设计

学长设计的系统采用的是非关系型数据库Elasticsearch,因此对于此数据库的查询等基本操作会加以图例的方式进行辅助阐述。在使用者开始进行査询时,系统不可能把使用者输入的关键词与所有本地数据进行匹配,这种检索方式即便建立索引,查询效率仍然较低,而且非常消耗服务器资源。

因此,Elasticsearch将获取到的数据分为两个阶段进行处理。第一阶段:采用合适的分词器,将获取到的数据按照分词器的标准进行分词,第二阶段:对每个关键词的频率以及出现的位置进行统计。

经过以上两个阶段,最后每个词语具体出现在哪些文章中,出现的位置和频次如何,都将会被保存到Elasticsearch数据库中,此过程即为构建倒排索引,需要花费的计算开销很大,但大大提高了后续检索的效率。其中,搜索引擎的索引过程流程图如图

在这里插入图片描述

2.2 搜索关键流程

如图所示,每一位用户在搜索框中输入关键字后,点击搜索发起搜索请求,系统后台解析内容后,将搜索结果返回到查询结果页,用户可以直接点击查询结果的标题并跳转到详情页,也可以点击下一页查看其他页面的搜索结果,也可以选择重新在输入框中输入新的关键词,再次发起搜索。

跳转至不同结果页流程图:

在这里插入图片描述

浏览具体网页信息流程图:

在这里插入图片描述

搜索功能流程图:
在这里插入图片描述

2.3 推荐算法

用户可在平台上了解到当下互联网领域中的热点内容,点击文章链接后即可进入到对应的详情页面中,浏览选中的信息的目标网页,详细了解其中的内容。丰富了本搜索平台提供信息的实时性,如图

在这里插入图片描述

用户可在搜索引擎首页中浏览到系统推送的可能感兴趣的内容,同时用户可点击推送的标题进入具体网页进行浏览详细内容。流程图如图

在这里插入图片描述

2.4 数据流的实现

学长设计的系统的数据来源主要是从发布互联网专业领域信息的开源社区上爬虫得到。

再经过IK分词器对获取到的标题和摘要进行分词,再由Elasticsearch建立索引并将数据持久化。

用户通过输入关键词,点击检索,后台程序对获得的关键词再进行分词处理,再到数据库中进行查找,将满足条件的网页标题和摘要用超链接的方式在浏览器中显示出来。

在这里插入图片描述

3 实现细节

3.1 系统架构

搜索引擎有基本的五大模块,分别是:

  • 信息采集模块
  • 信息处理模块
  • 建立索引模块
  • 查询和 web 交互模块

学长设计的系统目的是在信息处理分析的基础上,建立一个完整的中文搜索引擎。

所以该系统主要由以下几个详细部分组成:

  • 爬取数据
  • 中文分词
  • 相关度排序
  • 建立web交互。

3.2 爬取大量网页数据

爬取数据,实际上用的就是爬虫。

我们平时在浏览网页的时候,在浏览器里输入一个网址,然后敲击回车,我们就会看到网站的一些页面,那么这个过程实际上就是这个浏览器请求了一些服务器然后获取到了一些服务器的网页资源,然后我们看到了这个网页。

请求呢就是用程序来实现上面的过程,就需要写代码来模拟这个浏览器向服务器发起请求,然后获取这些网页资源。那么一般来说实际上获取的这些网页资源是一串HTML代码,这里面包含HTML标签,还有一

我们写完程序之后呢就让它一直运行着,它就能代替我们浏览器来向服务器发送请求,然后一直不停的循环的运行进行批量的大量的获取数据了,这就是爬虫的一个基本的流程。

一个通用的网络爬虫的框架如图所示:

在这里插入图片描述
这里给出一段爬虫,爬取自己感兴趣的网站和内容,并按照固定格式保存起来:

# encoding=utf-8# 导入爬虫包from selenium import webdriver
​    # 睡眠时间import time
​    import re
​    import os
​    import requests
​    # 打开编码方式utf-8打开# 睡眠时间 传入int为休息时间,页面加载和网速的原因 需要给网页加载页面元素的时间
    def s(int):
        time.sleep(int)


​     
​    # html/body/div[1]/table/tbody/tr[2]/td[1]/input# http://dmfy.emindsoft.com.cn/common/toDoubleexamp.doif __name__ == '__main__':
        #查询的文件位置
       # fR = open('D:\\test.txt','r',encoding = 'utf-8')
     
        # 模拟浏览器,使用谷歌浏览器,将chromedriver.exe复制到谷歌浏览器的文件夹内
        chromedriver = r"C:\\Users\\zhaofahu\\AppData\\Local\\Google\\Chrome\\Application\\chromedriver.exe"
        # 设置浏览器
        os.environ["webdriver.chrome.driver"] = chromedriver
        browser = webdriver.Chrome(chromedriver)
        # 最大化窗口 用不用都行
        browser.maximize_window()
      #  header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36'}
     
        # 要爬取的网页
        neirongs = []  # 网页内容
        response = []  # 网页数据
        travel_urls = []
        urls = []
        titles = []
        writefile = open("docs.txt", 'w', encoding='UTF-8')
        url = 'http://travel.yunnan.cn/yjgl/index.shtml'
        # 第一页
        browser.get(url)
        response.append(browser.page_source)
        # 休息时间
        s(3)
     
        # 第二页的网页数据
        #browser.find_element_by_xpath('// *[ @ id = "downpage"]').click()
        #s(3)
        #response.append(browser.page_source)
        #s(3)
     
        # 第三页的网页数据
        #browser.find_element_by_xpath('// *[ @ id = "downpage"]').click()
        #s(3)
        #response.append(browser.page_source)


​     
​        # 3.用正则表达式来删选数据
​        reg = r'href="(//travel.yunnan.cn/system.*?)"'# 从数据里爬取data。。。# 。travel_urls 旅游信息网址for i in range(len(response)):
​            travel_urls = re.findall(reg, response[i])# 打印出来放在一个列表里
        for i in range(len(travel_urls)):
            url1 = 'http:' + travel_urls[i]
            urls.append(url1)
            browser.get(url1)
            content = browser.find_element_by_xpath('/html/body/div[7]/div[1]/div[3]').text
            # 获取标题作为文件名
            b = browser.page_source
            travel_name = browser.find_element_by_xpath('//*[@id="layer213"]').text
            titles.append(travel_name)
        print(titles)
        print(urls)
        for j in range(len(titles)):
            writefile.write(str(j) + '\t\t' + titles[j] + '\t\t' + str(urls[j])+'\n')
     
        s(1)
        browser.close()


## 

3.3 中文分词

中文分词使用jieba库即可

jieba 是一个基于Python的中文分词工具对于一长段文字,其分词原理大体可分为三步:

1.首先用正则表达式将中文段落粗略的分成一个个句子。

2.将每个句子构造成有向无环图,之后寻找最佳切分方案。

3.最后对于连续的单字,采用HMM模型将其再次划分。

jieba分词分为“默认模式”(cut_all=False),“全模式”(cut_all=True)以及搜索引擎模式。对于“默认模式”,又可以选择是否使用
HMM 模型(HMM=True,HMM=False)。

3.4 相关度排序

上面已经根据用户的输入获取到了相关的网址数据。
获取到的数据中rows的形式如下
[(urlid1,wordlocation1_1,wordlocation1_2,wordlocation1_3…),(urlid2,wordlocation2_1,wordlocation2_2,wordlocation2_3…)]
列表的每个元素是一个元组,每个元素的内容是urlid和每个关键词在该文档中的位置。

wordids形式为[wordid1, wordid2, wordid3…],即每个关键词所对应的单词id

我们将会介绍几种排名算法,所谓排名也就是根据各自的规则为每个链接评分,评分越好。并且最终我们会将几种排名算法综合利用起来,给出最终的排名。既然要综合利用,那么我们就要先实现每种算法。在综合利用时会遇到几个问题。

1、每种排名算法评分机制不同,给出的评分尺度和含义也不尽相同
2、如何综合利用,要考虑每种算法的效果。为效果好的给与较大的权重。

我们先来考虑第一个问题,如何消除每种评分算法所给出的评分尺度和含义不相同的问题。
第2个问题,等研究完所有的算法以后再来考虑。

简单,使用归一化,将每个评分值缩放到0-1上,1代表最高,0代表最低。

对爬去到的数据进行排序, 有好几种排序算法:

第1个排名算法:根据单词位置进行评分的函数

我们可以认为对用户输入的多个关键词,在文档中,这些关键词出现的位置越靠前越好。比如我们往往习惯在文章的前面添加一些摘要性、概括性的描述。

     # 根据单词位置进行评分的函数.

        # rows是[(urlid1,wordlocation1_1,wordlocation1_2,wordlocation1_3...),(urlid2,wordlocation2_1,wordlocation2_2,wordlocation2_3...)]def locationscore(self,rows):
​            locations=dict([(row[0],1000000) for row in rows])for row in rows:
​                loc=sum(row[1:]) #计算每个链接的单词位置总和,越小说明越靠前if loc<locations[row[0]]:  #记录每个链接最小的一种位置组合
​                    locations[row[0]]=loc
​    

            return self.normalizescores(locations,smallIsBetter=1)


#### 

第2个排名算法:根据单词频度进行评价的函数

我们可以认为对用户输入的多个关键词,在文档中,这些关键词出现的次数越多越好。比如我们在指定主题的文章中会反复提到这个主题。

    
     # 根据单词频度进行评价的函数
        # rows是[(urlid1,wordlocation1_1,wordlocation1_2,wordlocation1_3...),(urlid2,wordlocation2_1,wordlocation2_2,wordlocation2_3...)]
        def frequencyscore(self,rows):
            counts=dict([(row[0],0) for row in rows])
            for row in rows: 
                counts[row[0]]+=1   #统计每个链接出现的组合数目。 每个链接只要有一种位置组合就会保存一个元组。所以链接所拥有的组合数,能一定程度上表示单词出现的多少。
            return self.normalizescores(counts)

第3个排名算法:根据单词距离进行评价的函数

我们可以认为对用户输入的多个关键词,在文档中,这些关键词出现的越紧凑越好。这是因为我们更希望所有单词出现在一句话中,而不是不同的关键词出现在不同段落或语句中。

# 根据单词距离进行评价的函数。# rows是[(urlid1,wordlocation1_1,wordlocation1_2,wordlocation1_3...),(urlid2,wordlocation2_1,wordlocation2_2,wordlocation2_3...)]def distancescore(self,rows):# 如果仅查询了一个单词,则得分都一样if len(rows[0])<=2: return dict([(row[0],1.0) for row in rows])# 初始化字典,并填入一个很大的值
            mindistance=dict([(row[0],1000000) for row in rows])
    
            for row in rows:
                dist=sum([abs(row[i]-row[i-1]) for i in range(2,len(row))]) # 计算每种组合中每个单词之间的距离
                if dist<mindistance[row[0]]:  # 计算每个链接所有组合的距离。并为每个链接记录最小的距离
                    mindistance[row[0]]=dist
            return self.normalizescores(mindistance,smallIsBetter=1)


4 实现效果

热门主题推荐实现

在这里插入图片描述

搜索界面的实现

在这里插入图片描述

查询结果页面显示

在这里插入图片描述

查询结果分页显示

在这里插入图片描述

查询结果关键字高亮标记显示

在这里插入图片描述

4 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/892036.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++基础语法——继承

1.继承是什么&#xff1f; 继承是一种面向对象编程的概念&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;从另一个类&#xff08;称为基类或父类&#xff09;继承属性和方法。继承使得子类能够使用基类已有的代码&#xff0c;并且可以在此基础上进行扩展或修…

【IEEE会议】第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023)

第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023&#xff09; 随着大数据时代的到来&#xff0c;对数据获取的随时性和对计算的需求也在逐渐增长。为推动大数据时代的云计算与软件工程的发展&#xff0c;促进该领域学术交流&#xff0c;在CBASE 2022成功举办的…

ChatGpt开源项目完美运行配置-ChatGml2

任务描述 本节任务是安装和配置chatgpt项目所需的软件以及chatgpt项目所需要的python库包&#xff0c;同时编写python代码来完成chatgpt项目的人机对话功能。 实验工具 显卡GTX1070&#xff08;专用内存需要大于等于6G&#xff09;以上电脑、Pycharm软件、Python3.10软件、cud…

船舶法兰盘法兰管件3D扫描尺寸测量|三维扫描检测|CAV测量-CASAIM

第一章 服务背景 船舶建造多采用分段建造法&#xff0c;即将零件、预装好的部件在胎架上组合焊接成分段或总段&#xff0c;然后由船台装配成整船的建造方法。而当船体合拢组装时&#xff0c;在船体上遍布着各种各样的管道&#xff0c;这些管道都需要互相完全适配以确保船体安装…

python print 输出格式化的几种方式

# 对浮点数&#xff0c;保留小数点后几位 print({:0.3f}.format(50.5 / 220.5)) # print 格式化字符串 num int(input(请输入一个十进制的整数&#xff1a;)) # 将str 转为int类型 print(num, 的二进制数为&#xff1a;, bin(num)) # 第一种写法使用了个数可变的位置参数 pr…

JavaWeb_LeadNews_Day6-Kafka

JavaWeb_LeadNews_Day6-Kafka Kafka概述安装配置kafka入门kafka高可用方案kafka详解生产者同步异步发送消息生产者参数配置消费者同步异步提交偏移量 SpringBoot集成kafka 自媒体文章上下架实现思路具体实现 来源Gitee Kafka 概述 对比 选择 介绍 producer: 发布消息的对象称…

JVM——配置常用参数,GC调优策略

文章目录 JVM 配置常用参数Java内存区域常见配置参数概览堆参数回收器参数项目中常用配置常用组合 常用 GC 调优策略GC 调优原则GC 调优目的GC 调优策略 JVM 配置常用参数 Java内存区域常见配置参数概览堆参数&#xff1b;回收器参数&#xff1b;项目中常用配置&#xff1b;常…

一、数学建模之线性规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.线性规划&#xff08;Linear Programming&#xff0c;简称LP&#xff09;是一种数学优化技术&#xff0c;线性规划作为运筹学的一个重要分支&#xff0c;专门研究在给定一组线性约束条件下&#xff0c;如何找到一个最优的决策&…

YOLOv1基础

目录 深度学习经典检测方法指标分析核心思想网络架构损失函数非极大值抑制优缺点 深度学习经典检测方法 预选框&#xff0c;在论文中叫RPN&#xff0c;也就是区域建议网络 指标分析 核心思想 网络架构 损失函数 非极大值抑制 优缺点

【java毕业设计】基于Spring Boot+Vue+mysql的论坛管理系统设计与实现(程序源码)-论坛管理系统

基于Spring BootVuemysql的论坛管理系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring BootVuemysql的论坛管理系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取…

ssh远程连接慢解决方法

一、关闭SERVER上的GSS认证 将GSSAPIAuthentication改为no ,如果在配置文件中&#xff0c;以下值是被注释的就拿掉注释&#xff0c;因为默认开关就是yes # vi /etc/ssh/sshd_config GSSAPIAuthentication no二、关闭SERVER上DNS反向解析 在linux中&#xff0c;默认就是开启了S…

java代码审计11.1之反序列化基础学习

文章目录 1、 序列化与反序列化2、序列化与反序列化案例2.1、使用idea生成代码与serialVersionUID2.2、实例化对象2.3、序列化对象2.4、反序列化 3、稍微深入serialVersionUID综上小结&#xff0c; 4、transient 作⽤5、反序列化漏洞 之前的文章&#xff0c; php代码审计15.1之…

部署piwigo网页 通过cpolar分享本地电脑上的图片

通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页 文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页前言1. 设定一条内网穿透数据隧道2. 与piwigo网站绑定3. 在创建隧道界面填写关键信息4. 隧道创建完成 总结 前言 首先在本地电脑上部署…

微服务最佳实践,零改造实现 Spring Cloud Apache Dubbo 互通

作者&#xff1a;孙彩荣 很遗憾&#xff0c;这不是一篇关于中间件理论或原理讲解的文章&#xff0c;没有高深晦涩的工作原理分析&#xff0c;文后也没有令人惊叹的工程数字统计。本文以实际项目和代码为示例&#xff0c;一步一步演示如何以最低成本实现 Apache Dubbo 体系与 S…

k8s集群监控方案--node-exporter+prometheus+grafana

目录 前置条件 一、下载yaml文件 二、部署yaml各个组件 2.1 node-exporter.yaml 2.2 Prometheus 2.3 grafana 2.4访问测试 三、grafana初始化 3.1加载数据源 3.2导入模板 四、helm方式部署 前置条件 安装好k8s集群&#xff08;几个节点都可以&#xff0c;本人为了方便实验k8s集…

搭载KaihongOS的工业平板、机器人、无人机等产品通过3.2版本兼容性测评,持续繁荣OpenHarmony生态

近日&#xff0c;搭载深圳开鸿数字产业发展有限公司&#xff08;简称“深开鸿”&#xff09;KaihongOS软件发行版的工业平板、机器人、无人机等商用产品均通过OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;3.2 Release版本兼容性测评&#xff0c;获颁O…

探索Perfetto:开源性能追踪工具的未来之光

探索Perfetto&#xff1a;开源性能追踪工具的未来之光 1. 引言 A. 介绍Perfetto的背景和作用 随着移动应用、桌面软件和嵌入式系统的不断发展&#xff0c;软件性能优化变得愈发重要。在这个背景下&#xff0c;Perfetto作为一款开源性能追踪工具&#xff0c;日益引起了开发者…

LangChain手记 Agent 智能体

整理并翻译自DeepLearning.AILangChain的官方课程&#xff1a;Agent&#xff08;源代码可见&#xff09; “人们有时会将LLM看作是知识库&#xff0c;因为它被训练所以记住了来自互联网或其他地方的海量信息&#xff0c;因而当你向它提问时&#xff0c;它可以回答你的问题。有一…

centos7 yum获取软件所有依赖包 创建本地yum源 yum离线安装软件

centos7 yum获取软件所有依赖包 创建本地yum源 离线安装软件 1、以安装docker 20.10为例2、centos7 yum获取docker 20.10 所有依赖包3、创建本地docker yum源4、yum使用本地docker源 离线安装docker 1、以安装docker 20.10为例 参考链接&#xff1a; 添加docker 清华软件源 y…

Spring Clould 搜索技术 - elasticsearch

视频地址&#xff1a;微服务&#xff08;SpringCloudRabbitMQDockerRedis搜索分布式&#xff09; 初识ES-什么是elasticsearch&#xff08;P77&#xff0c;P78&#xff09; 1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能…