当前位置: 首页 > news >正文

竞赛选题 python的搜索引擎系统设计与实现

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"] = chromedriverbrowser = 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_sourcetravel_name = browser.find_element_by_xpath('//*[@id="layer213"]').texttitles.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]]=distreturn self.normalizescores(mindistance,smallIsBetter=1)

4 实现效果

热门主题推荐实现

在这里插入图片描述

搜索界面的实现

在这里插入图片描述

查询结果页面显示

在这里插入图片描述

查询结果分页显示

在这里插入图片描述

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

在这里插入图片描述

4 最后

🧿 更多资料, 项目分享:

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

相关文章:

竞赛选题 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…...

大模型技术方向夏令营1期-对话分角色要素提取挑战赛

#AI夏令营 #Datawhale #夏令营 一、 baseline 跑通 Baseline 本身挑战性有限&#xff0c;关键是熟悉 LLM-centric 相关任务 coding 层面的流程方法&#xff0c;比如: 大模型 API&#xff08;这里为科大讯飞 Spark&#xff09;调用token消耗的理解如何调用大模型实现针对给定…...

类和对象(封装、继承、多态、友元)

c面相对象的三大特性为&#xff1a;封装、继承、多态 c 认为万事万物都皆为对象&#xff0c;对象上有其属性和行为 一、类和对象&#xff08;封装&#xff09; &#xff08;一&#xff09;封装的意义 封装是c面相对象的三大特性之一 封装的意义&#xff1a; 将属性和行为…...

关于Yolov8我踩过的那些坑

按照报错频次梳理&#xff1a; 致命反斜杠‘\’ 调用模型时&#xff0c;我喜欢‘copy relative location’&#xff0c;然后win系统默认反斜杠&#xff01; 就导致路径读取错误&#xff01;各种报错&#xff01;&#xff01; debug到崩溃然后发现是斜杠的问题&#xff0c;本吗喽…...

Linux——shell原理和文件权限

1.shell原理 在我们使用云服务器时&#xff0c;需要通过shell进行使用&#xff0c;而shell则是一种外壳程序。 我们提到过&#xff0c;大部分的指令实际上就是文件&#xff0c;当用户需要执行某种功能时&#xff0c;由于用户不擅长和操作系统直接交互&#xff08;操作复杂&…...

网络工程师需要熟悉Docker吗?我觉得不需要精通,但是得懂基础

你好&#xff0c;这里是网络技术联盟站&#xff0c;我是瑞哥。 Docker&#xff0c;这个字眼大家不陌生吧&#xff0c;不过作为网络工程师可能平时接触不到&#xff0c;如果在看文章的是运维人员&#xff0c;那么70%以上的运维人员都会跟Docker打交道。即使网工用不到&#xff…...

c++初级-2-引用

文章目录 引用一、引用的定义二、引用做函数参数三、引用作为返回对象四、引用的本质五、常量引用 引用 即给一个变量起别名。 一、引用的定义 int a 10;//引用int& b a;cout << "a " << a << endl;cout << "b " <&l…...

如何清理电脑内存?让电脑运行如飞!

电脑内存&#xff08;RAM&#xff09;的清理对于维持系统的流畅运行至关重要。随着使用时间的增加&#xff0c;系统内存会被各种应用程序和后台进程占用&#xff0c;导致系统响应变慢&#xff0c;甚至出现卡顿现象。通过有效地清理内存&#xff0c;可以提升电脑的性能&#xff…...

[数据集][目标检测]人员状态跑睡抽烟打电话跌倒检测数据集4943张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4943 标注数量(xml文件个数)&#xff1a;4943 标注数量(txt文件个数)&#xff1a;4943 标注…...

Java8 - Stream API 处理集合数据

Java 8的Stream API提供了一种功能强大的方式来处理集合数据&#xff0c;以函数式和声明式的方式进行操作。Stream API允许您对元素集合执行操作&#xff0c;如过滤、映射和归约&#xff0c;以简洁高效的方式进行处理。 下面是Java 8 Stream API的一些关键特性和概念&#xff…...

漫步5G-A City,一份独属于上海的浪漫

作家亨利詹姆斯曾写道&#xff0c;“城市漫步&#xff0c;让我接触到了这个世界上最好的东西”。 用漫无目的地行走&#xff0c;来体验和观察一座城市&#xff0c;上海凭借丰富多元的文化特质&#xff0c;成为citywalk这种浪漫生活方式的流行地。 无论你是漫步在美术馆、画廊林…...

SpringBoot 如何处理跨域请求?你说的出几种方法?

引言&#xff1a;在现代的Web开发中&#xff0c;跨域请求&#xff08;Cross-Origin Resource Sharing&#xff0c;CORS&#xff09;是一个常见的挑战。随着前后端分离架构的流行&#xff0c;前端应用通常运行在一个与后端 API 不同的域名或端口上&#xff0c;这就导致了浏览器的…...

OV SSL证书年度成本概览:为企业安全护航的经济之选

在当今数字化时代&#xff0c;企业网站不仅是品牌展示的窗口&#xff0c;更是与客户沟通的桥梁。然而&#xff0c;随着网络威胁的不断升级&#xff0c;保护网站安全成为了企业不可忽视的任务。SSL证书&#xff0c;特别是OV SSL证书&#xff0c;因其对企业身份的严格验证&#x…...

歌尔气压计SPA06-003在无人机的创新应用

随着科技的不断进步&#xff0c;各类智能设备的功能日益强大&#xff0c;其中气压计作为一种能够测量大气压力的传感器&#xff0c;已被广泛应用于多种领域。歌尔气压计以其高精度、低功耗的特点&#xff0c;在无人机和智能手表上的应用尤为突出&#xff0c;为这两个领域的产品…...

python3多文件操作

1 介绍 有两个.py文件&#xff0c;分别为main.py和util.py&#xff0c;执行main.py时&#xff0c;调用util.py当中的函数。 main.py内容如下&#xff0c; import util if __name__ "__main__":a [3.0,4.0]length util.get_length_from_vec(a)print(f"leng…...

312. 戳气球

312. 戳气球 题目链接&#xff1a;312. 戳气球 代码如下&#xff1a; //参考链接:https://leetcode.cn/problems/burst-balloons/solutions/336390/chuo-qi-qiu-by-leetcode-solution class Solution { public:int maxCoins(vector<int>& nums) {int nnums.size()…...

深入理解C++中的锁

目录 1.基本互斥锁&#xff08;std::mutex&#xff09; 2.递归互斥锁&#xff08;std::recursive_mutex&#xff09; 3.带超时机制的互斥锁&#xff08;std::timed_mutex&#xff09; 4.带超时机制的递归互斥锁&#xff08;std::recursive_timed_mutex&#xff09; 5.共享…...

压缩pdf文件大小,压缩pdf文件大小软件哪个好

在数字化时代&#xff0c;PDF文件因其卓越的跨平台兼容性和稳定性而成为工作与学习的好帮手。然而&#xff0c;当PDF文件体积过大时&#xff0c;传输和存储便成了一项挑战。别担心&#xff0c;本文将为你揭秘如何快速压缩PDF文件&#xff0c;让你的文档轻装上路&#xff01; 压…...

难道 Java 已经过时了?

当一门技术已经存在许多年了&#xff0c;它可能会失去竞争力&#xff0c;而后黯然退场&#xff0c;默默地离开&#xff0c;这对大部分的人来说就已经算是过时了。 Java 于 1995 年正式上线&#xff0c;至今已经走过了 27 个年头&#xff0c;在众多编程技术里算是年龄比较大的语…...

华为OD机考题(​HJ32 密码截取)

前言 经过前期的数据结构和算法学习&#xff0c;开始以OD机考题作为练习题&#xff0c;继续加强下熟练程度。有需要的可以同步练习下。 描述 Catcher是MCA国的情报员&#xff0c;他工作时发现敌国会用一些对称的密码进行通信&#xff0c;比如像这些ABBA&#xff0c;ABA&…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...