返回顶部
首页 > 资讯 > 后端开发 > Python >Python实战之手写一个搜索引擎
  • 540
分享到

Python实战之手写一个搜索引擎

2024-04-02 19:04:59 540人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录一、前言二、工作流程三、数据模块四、索引模块五、搜索模块一、前言 这篇文章,我们将会尝试从零搭建一个简单的新闻搜索引擎 当然,一个完整的搜索引擎十分复杂,这里我们只介绍其中最为核

一、前言

这篇文章,我们将会尝试从零搭建一个简单的新闻搜索引擎

当然,一个完整的搜索引擎十分复杂,这里我们只介绍其中最为核心的几个模块

分别是数据模块、排序模块和搜索模块,下面我们会逐一讲解,这里先从宏观上看一下它们之间的工作流程

二、工作流程

在这里插入图片描述

三、数据模块

数据模块的主要作用是爬取网络上的数据,然后对数据进行清洗并保存到本地存储

一般来说,数据模块会采用非定向爬虫技术广泛爬取网络上的数据,以保证充足的数据源

但是由于本文只是演示,所以这里我们仅会采取定向爬虫爬取中国社会科学网上的部分文章素材

而且因为爬虫技术我们之前已经讲过很多,这里就不打算细讲,只是简单说明一下流程

首先我们定义一个数据模块类,名为 DataLoader,类中有一个核心变量 data 用于保存爬取下来的数据

以及两个相关的接口 grab_data (爬取数据) 和 save_data (保存数据到本地)

grab_data() 的核心逻辑如下:

1.首先调用 get_entry(),获取入口链接


def get_entry(self):
    baseurl = 'Http://his.CSSn.cn/lsx/sjls/'
    entries = []
    for idx in range(5):
        entry = baseurl if idx == 0 else baseurl + 'index_' + str(idx) + '.shtml'
        entries.append(entry)
    return entries

2.然后调用 parse4links(),遍历入口链接,解析得到文章链接


def parse4links(self, entries):
    links = []
    headers = {
        'USER-AGENT': 'Mozilla/5.0 (windows NT 10.0; WOW64) AppleWEBKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    for entry in entries:
        try:
            response = requests.get(url = entry, headers = headers)
            html = response.text.encode(response.encoding).decode('utf-8')
            time.sleep(0.5)
        except:
            continue

        html_parser = etree.HTML(html)
        link = html_parser.xpath('//div[@class="ImageListView"]/ol/li/a/@href')
        link_filtered = [url for url in link if 'www' not in url]
        link_complete = [entry + url.lstrip('./') for url in link_filtered]
        links.extend(link_complete)

    return links

3.接着调用 parse4datas(),遍历文章链接,解析得到文章内容


def parse4datas(self, entries):
    datas = []
    headers = {
        'USER-AGENT': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
    }
    data_count = 0
    for entry in entries:
        try:
            response = requests.get(url = entry, headers = headers)
            html = response.text.encode(response.encoding).decode('utf-8')
            time.sleep(0.2)
        except:
            continue

        html_parser = etree.HTML(html)
        title = html_parser.xpath('//span[@class="TitleFont"]/text()')
        content = html_parser.xpath('//div[@class="TRS_Editor"]//p//text()')
        content = [cont.replace('\u3000', '').replace('\xa0', '').replace('\n', '').replace('\t', '') for cont in content]
        content = [cont for cont in content if len(cont) > 30 and not re.search(r'[《|》]', cont)]

        if len(title) != 0 or len(content) != 0:
            data_count += 1
            datas.append({
                'id'  : data_count,
                'link': entry,
                'cont': '\t'.join(content),
                'title': title[0]
            })

    return datas

grab_data() 的核心代码如下:


def grab_data(self):
    # 获取入口链接
    entries = self.get_entry()
    # 遍历入口链接,解析得到文章链接
    links = self.parse4links(entries)
    # 遍历文章链接,解析得到文章内容
    datas = self.parse4datas(links)
    # 将相关数据写入变量 data
    self.data = pd.DataFrame(datas)

save_data() 的核心代码如下:


def save_data(self):
    # 将变量 data 写入 csv 文件
    self.data.to_csv(self.data_path, index = None)

至此,我们已经爬取并保存好数据 data,数据以 DataFrame 形式存储,保存在 csv 文件,格式如下:


|---------------------------------------------------|
|    id    |     link   |     cont     |    title   |
|---------------------------------------------------|
|  page id |  page link | page content | page title |
|---------------------------------------------------|
|  ......  |   ......   |    ......    |   ......   |
|---------------------------------------------------|

四、索引模块

索引模型的主要作用是构建倒排索引 (inverted index),这是搜索引擎中十分关键的一环

一般来说,构建索引的目的就是为了提高查询速度

普通的索引一般是通过文章标识索引文章内容,而倒排索引则正好相反,通过文章内容索引文章标识

具体来说,倒排索引会以文章中出现过的词语作为键,以该词所在的文章标识作为值来构建索引

首先我们定义一个索引模块类,名为 IndexModel,类中有一个核心变量 iindex 用于保存倒排索引

以及两个相关的接口 make_iindex (构建索引) 和 save_iindex (保存索引到本地)

make_iindex() 的核心代码如下(具体逻辑请参考注释):


def make_iindex(self):
    # 读取数据
    df = pd.read_csv(self.data_path)
    # 特殊变量,用于搜索模块
    TOTAL_DOC_NUM = 0 # 总文章数量
    TOTAL_DOC_LEN = 0 # 总文章长度
    # 遍历每一行
    for row in df.itertuples():
        doc_id = getattr(row, 'id') # 文章标识
        cont = getattr(row, 'cont') # 文章内容

        TOTAL_DOC_NUM += 1
        TOTAL_DOC_LEN += len(cont)

        # 对文章内容分词
        # 并将其变成 {Word: frequency, ...} 的形式
        cuts = jieba.lcut_for_search(cont)
        word2freq = self.fORMat(cuts)

        # 遍历每个词,将相关数据写入变量 iindex
        for word in word2freq:
            meta = {
                'id': doc_id,
                'dl': len(word2freq),
                'tf': word2freq[word]
            }
            if word in self.iindex:
                self.iindex[word]['df'] = self.iindex[word]['df'] + 1
                self.iindex[word]['ds'].append(meta)
            else:
                self.iindex[word] = {}
                self.iindex[word]['df'] = 1
                self.iindex[word]['ds'] = []
                self.iindex[word]['ds'].append(meta)

    # 将特殊变量写入配置文件
    self.config.set('DATA', 'TOTAL_DOC_NUM', str(TOTAL_DOC_NUM)) # 文章总数
    self.config.set('DATA', 'AVG_DOC_LEN', str(TOTAL_DOC_LEN / TOTAL_DOC_NUM)) # 文章平均长度
    with open(self.option['filepath'], 'w', encoding = self.option['encoding']) as config_file:
        self.config.write(config_file)

save_iindex() 的核心代码如下:


def save_iindex(self):
    # 将变量 iindex 写入 JSON 文件
    fd = open(self.iindex_path, 'w', encoding = 'utf-8')
    json.dump(self.iindex, fd, ensure_ascii = False)
    fd.close()

至此,我们们经构建并保存好索引 iindex,数据以 JSON 形式存储,保存在 json 文件,格式如下:


{
    word: {
        'df': document_frequency,
        'ds': [{
            'id': document_id,
            'dl': document_length,
            'tf': term_frequency
        }, ...]
    },
    ...
}

五、搜索模块

在得到原始数据和构建好倒排索引后,我们就可以根据用户的输入查找相关的内容

具体怎么做呢?

1.首先我们对用户的输入进行分词

2.然后根据倒排索引获取每一个词相关的文章

3.最后计算每一个词与相关文章之间的得分,得分越高,说明相关性越大

这里我们定义一个搜索模块类,名为 SearchEngine,类中有一个核心函数 search 用于查询搜索


def search(self, query):
    BM25_scores = {}

    # 对用户输入分词
    # 并将其变成 {word: frequency, ...} 的形式
    query = jieba.lcut_for_search(query)
    word2freq = self.format(query)

    # 遍历每个词
    # 计算每个词与相关文章之间的得分(计算公式参考 BM25 算法)
    for word in word2freq:
        data = self.iindex.get(word)
        if not data:
            continue
        BM25_score = 0
        qf = word2freq[word]
        df = data['df']
        ds = data['ds']
        W = math.log((self.N - df + 0.5) / (df + 0.5))
        for doc in ds:
            doc_id = doc['id']
            tf = doc['tf']
            dl = doc['dl']
            K = self.k1 * (1 - self.b + self.b * (dl / self.AVGDL))
            R = (tf * (self.k1 + 1) / (tf + K)) * (qf * (self.k2 + 1) / (qf + self.k2))
            BM25_score = W * R
            BM25_scores[doc_id] = BM25_scores[doc_id] + BM25_score if doc_id in BM25_scores else BM25_score

    # 对所有得分按从大到小的顺序排列,返回结果
    BM25_scores = sorted(BM25_scores.items(), key = lambda item: item[1])
    BM25_scores.reverse()
    return BM25_scores

到此这篇关于python实战之手写一个搜索引擎的文章就介绍到这了,更多相关Python写搜索引擎内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python实战之手写一个搜索引擎

本文链接: https://lsjlt.com/news/124763.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python实战之手写一个搜索引擎
    目录一、前言二、工作流程三、数据模块四、索引模块五、搜索模块一、前言 这篇文章,我们将会尝试从零搭建一个简单的新闻搜索引擎 当然,一个完整的搜索引擎十分复杂,这里我们只介绍其中最为核...
    99+
    2024-04-02
  • MySQL中怎么实现一个搜索引擎
    本篇文章为大家展示了MySQL中怎么实现一个搜索引擎,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。前言 只有Innodb和myisam存储引擎能用全文索引...
    99+
    2024-04-02
  • 浅谈用Python实现一个大数据搜索引擎
    搜索是大数据领域里常见的需求。Splunk和ELK分别是该领域在非开源和开源领域里的领导者。本文利用很少的Python代码实现了一个基本的数据搜索功能,试图让大家理解大数据搜索的基本原理。 布隆过滤器 (B...
    99+
    2022-06-04
    浅谈 搜索引擎 数据
  • 基于 Mysql 实现一个简易版搜索引擎
    目录基于 Mysql 实现一个搜索引擎一、ngram 全文解析器二、创建全文索引1、建表时创建全文索引2、通过 alter table 方式3、通过 create index 方式三...
    99+
    2024-04-02
  • PHP中怎么实现一个站内搜索引擎
    这篇文章将为大家详细讲解有关PHP中怎么实现一个站内搜索引擎,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。PHP实现站内搜索引擎的具体代码:<   inc...
    99+
    2023-06-17
  • CMS与搜索引擎的完美结合:如何打造一个搜索引擎友好的网站
    CMS(内容管理系统)是一种软件工具,可以帮助您轻松创建、管理和更新网站内容。CMS 使得非技术人员也可以轻松创建一个专业美观的网站。除了方便管理内容外,CMS 还具有许多有助于 SEO 的功能,可以帮助您提升网站在搜索引擎中的排名。 ...
    99+
    2024-02-02
    CMS 网站 搜索引擎 SEO 网站优化
  • Python搜索引擎实现原理和方法
    如何在庞大的数据中高效的检索自己需要的东西?本篇内容介绍了Python做出一个大数据搜索引擎的原理和方法,以及中间进行数据分析的原理也给大家做了详细介绍。 布隆过滤器 (Bloom Filter) 第一步我...
    99+
    2022-06-04
    原理 搜索引擎 方法
  • 怎么在Spring Boot中使用ElasticSearch实现一个搜索引擎
    这篇文章将为大家详细讲解有关怎么在Spring Boot中使用ElasticSearch实现一个搜索引擎,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Elastic Search是一个开源的...
    99+
    2023-05-30
    springboot elasticsearch
  • CMS URL 重写:搜索引擎优化之旅的必备指南
    用户体验增强 易于阅读和记忆的 URL 可以改善用户体验,因为它们能清楚地传达页面内容。 简洁的 URL 消除了冗余的查询字符串和会话 ID,使 URL 更短、更简洁。 搜索引擎优化优势 关键字丰富的 URL 可以将相关关键字包含在...
    99+
    2024-04-02
  • 如何在自己的网站安装一个搜索引擎
    这篇文章将为大家详细讲解有关如何在自己的网站安装一个搜索引擎,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。  1、安装自己的搜索引擎脚本  安装Perl搜索引擎脚本或PHP搜索引擎的脚本 。 这需要你在设...
    99+
    2023-06-10
  • Python利用3D引擎写一个Pong游戏
    目录前言实现方法完整代码前言 之前,我们用pygame做了一个2D的Pong游戏,今天我们做一个3D的,游戏画面如下: 用ad和←→操作,双人对战 实现该效果我...
    99+
    2023-01-05
    Python 3D Pong游戏 Python Pong游戏 Python 游戏
  • 如何使用MySQL和Java实现一个简单的搜索引擎功能
    要使用MySQL和Java实现一个简单的搜索引擎功能,可以按照以下步骤进行:1. 创建数据库:首先,使用MySQL Workbenc...
    99+
    2023-10-20
    MySQL
  • python基于搜索引擎实现文章查重功能
    前言 文章抄袭在互联网中普遍存在,很多博主都收受其烦。近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制、黏贴后发布标原创屡见不鲜,部分抄袭后的文章甚至标记了一些联...
    99+
    2024-04-02
  • 异步协程开发实战:构建高性能的实时搜索引擎
    异步协程开发实战:构建高性能的实时搜索引擎引言:在当今大数据时代,高性能的实时搜索引擎对于处理海量数据、提供快速准确的搜索结果变得越来越重要。而异步协程开发技术的出现,为我们构建高性能的实时搜索引擎提供了一种全新的解决方案。本文将深入探讨什...
    99+
    2023-12-09
    异步 协程 实时搜索
  • Python学习教程:手把手教你使用Flask搭建ES搜索引擎
    Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库Apache Lucene™ 基础之上。那么如何实现 Elasticsearch和 Python 的对接成为我们所关心的问题了 (怎么什么都要和 Python 关联啊...
    99+
    2023-06-01
  • VUE SEO优化指南:打造一个搜索引擎友好的网站
    Vue作为一款流行的前端框架,以其灵活性和高性能而备受青睐。然而,与传统的静态网站相比,Vue驱动的单页应用(SPA)在SEO方面存在一定的劣势。 原因在于,SPA在加载页面时,不会像传统网站那样重新加载整个页面。而是通过JavaScri...
    99+
    2024-02-11
    Vue SEO优化 搜索引擎优化 Vue前端框架 SEO指南
  • python基于搜索引擎如何实现文章查重功能
    这篇文章给大家分享的是有关python基于搜索引擎如何实现文章查重功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络爬虫...
    99+
    2023-06-14
  • 用python实现一个文件搜索工具
    目录前言步骤操作如下:完整代码:总结前言 经常使用电脑自带的搜索很慢很卡,今天做一个搜索工具,可以搜索到隐藏的文件,而且速度也很快 步骤 导入模块 import os 检测一下输入的...
    99+
    2024-04-02
  • Python实战之MNIST手写数字识别详解
    目录数据集介绍1.数据预处理2.网络搭建3.网络配置关于优化器关于损失函数关于指标4.网络训练与测试5.绘制loss和accuracy随着epochs的变化图6.完整代码数据集介绍 ...
    99+
    2024-04-02
  • 从零开始学习GO与Apache索引接口:如何快速构建一个高质量的搜索引擎?
    在当今信息化的时代,搜索引擎是人们获取信息的主要途径之一,而构建一个高质量的搜索引擎是每个搜索引擎从业者的梦想。本文将介绍如何使用GO语言和Apache索引接口快速构建一个高质量的搜索引擎。 一、GO语言简介 GO语言是Google开发的...
    99+
    2023-10-19
    apache 索引 接口
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作