python实现简易搜索引擎(含代码)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: python实现简易搜索引擎(含代码)

今天我们使用python来搭建简易的搜索引擎。

搜索引擎的本质其实就是对数据的预处理,分词构建索引和查询。

(这边我们默认所有的数据都是utf-8的数据类型)


我们在一个网站上去获取所有的URL:


def crawl(pages,depth=2):
    for i in range(depth):
        newpages = set()
        for page in pages:
            try:
                c = urllib.request.urlopen(page)
            except:
                print('Invaild page:',page)
                continue
            soup = bs4.BeautifulSoup(c.read())
            links = soup('a')
            for link in links:
                if('href' in dict(link.attrs)):
                    url = urllib.urljoin(page,link['href'])
                    if url.find("'")!=-1:continue
                    url = url.split('#')[0]
                    if url[0:3]=='http':
                        newpages.add(url)
        pages = newpages

通过一个循环抓取当前页面上所有的链接,我们尽可能多的去抓取链接,之所以选择set而不使用list是防止重复的现象,我们可以将爬取的的网站存放到文件或者MySQL或者是MongoDB里。


output = sys.stdout
outputfile = open('lujing.txt', 'w')
sys.stdout = outputfile
list = GetFileList(lujing, [])

将生成的路径文件lujing.txt读取,并按照路径文件对文本处理


# 将生成的路径文件lujing.txt读取,并按照路径文件对文本处理,去标签
for line in open("lujing.txt"):
    print(line)
    # line=line[0:-2]
    line1 = line[0:12]
    line2 = line[13:16]
    line3 = line[17:-1]
    line4 = line[17:-6]
    line = line1 + '\\' + line2 + '\\' + line3
    print(line4)
    path = line
    fb = open(path, "rb")
    data = fb.read()
    bianma = chardet.detect(data)['encoding']  # 获取当前文件的编码方式,并按照此编码类型处理文档
    page = open(line, 'r', encoding=bianma, errors='ignore').read()
    dr = re.compile(r'<[^>]+>', re.S)  # 去HTML标签
    dd = dr.sub('', page)
    print(dd)
    fname = 'TXT' + "\\" + line4 + ".txt"
    # print(fname)
    f = open(fname, "w+", encoding=bianma)  # 将去标签的文件写到文件夹内,并按照原命名以txt文档方式保存
    # fo=open(fname,"w+")
    f.write(dd)



下面我们进行分词索引:

因为大家都比较熟悉sql语句那我在这里就写成MySQL的版本了,如果需要mongodb的可以私信公众号。


import jieba
import chardet
import pymysql
import importlib, sys
importlib.reload(sys)
# 如果使用MongoDB
# from pymongo import MongoClient
# #data processing
# client = MongoClient('localhost',27017)
# apiDB = client['urlDB']    #serverDB_name:test_nodedata
# questionnaires = apiDB['weburl']
# data = list(questionnaires.find())
conn = pymysql .connect(host="localhost",user="root",
                       password="123456",db="suoyin",port=3307)
conn.text_factory = str
c = conn.cursor()
c.execute('drop table doc')
c.execute('create table doc (id int primary key,link text)')
c.execute('drop table word')
c.execute('create table word (term varchar(25) primary key,list text)')
conn.commit()
conn.close()
def Fenci():
    num = 0
    for line in open("url.txt"):
        lujing = line
        print(lujing)
        num += 1
        print(line)
        line = line[17:-5]
        print(line)
        line = 'TXT' + '\\' + line + 'Txt'  # line为文件位置
        print(line)  # 文件名称
        path = line
        fb = open(path, "rb")
        data = fb.read()
        bianma = chardet.detect(data)['encoding']  # 获取文件编码        print(bianma)
        # page = open(line, 'r', encoding=bianma, errors='ignore').read()
        # page1=page.decode('UTF-8')
        if bianma == 'UTF-16':
            data = data.decode('UTF-16')
            data = data.encode('utf-8')
        word = jieba.cut_for_search(data)
        seglist = list(word)
        print(seglist)
        # 创建数据库
        c = conn.cursor()  # 创建游标
        c.execute('insert into doc values(?,?)', (num, lujing))
        # 对每个分出的词语建立词表
        for word in seglist:
            # print(word)
            # 检验看看这个词语是否已存在于数据库
            c.execute('select list from word where term=?', (word,))
            result = c.fetchall()
            # 如果不存在
            if len(result) == 0:
                docliststr = str(num)
                c.execute('insert into word values(?,?)', (word, docliststr))
            # 如果已存在
            else:
                docliststr = result[0][0]  # 得到字符串
                docliststr += ' ' + str(num)
                c.execute('update word set list=? where term=?', (docliststr, word))
        conn.commit()
        conn.close()
Fenci()


最后一步,查询:


import pymsql
import jieba
import math
conn = pymysql .connect(host="localhost",user="root",
                       password="123456",db="suoyin",port=3307)
c = conn.cursor()
c.execute('select count(*) from doc')
N = 1 + c.fetchall()[0][0]  # 文档总数
target = input('请输入搜索词:')
seggen = jieba.cut_for_search(target)
score = {}  # 文档号:匹配度
for word in seggen:
    print('得到查询词:', word)
    # 计算score
    tf = {}  # 文档号:文档数
    c.execute('select list from word where term=?', (word,))
    result = c.fetchall()
    if len(result) > 0:
        doclist = result[0][0]
        doclist = doclist.split(' ')
        # 把字符串转换为元素为int的list
        doclist = [int(x) for x in doclist]
        # 当前word对应的df数
        df = len(set(doclist))
        idf = math.log(N / df)
        print('idf:', idf)
        for num in doclist:
            if num in tf:
                tf[num] = tf[num] + 1
            else:
                tf[num] = 1
        # tf统计结束,现在开始计算score
        for num in tf:
            if num in score:
                # 如果该num文档已经有分数了,则累加
                score[num] = score[num] + tf[num] * idf
            else:
                score[num] = tf[num] * idf
sortedlist = sorted(score.items(), key=lambda d: d[1], reverse=True)
cnt = 0
for num, docscore in sortedlist:
    cnt = cnt + 1
    c.execute('select link from doc where id=?', (num,))
    url = c.fetchall()[0][0]
    print("Result Ranking:", cnt)
    print('url:', url, 'match degree:', docscore)
    if cnt > 20:
        break
if cnt == 0:
    print('No result')


搞定。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
缓存 开发者 Python
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第35天】装饰器在Python中是一种强大的工具,它允许开发者在不修改原有函数代码的情况下增加额外的功能。本文旨在通过简明的语言和实际的编码示例,带领读者理解装饰器的概念、用法及其在实际编程场景中的应用,从而提升代码的可读性和复用性。
|
2天前
|
设计模式 缓存 监控
Python中的装饰器:代码的魔法增强剂
在Python编程中,装饰器是一种强大而灵活的工具,它允许程序员在不修改函数或方法源代码的情况下增加额外的功能。本文将探讨装饰器的定义、工作原理以及如何通过自定义和标准库中的装饰器来优化代码结构和提高开发效率。通过实例演示,我们将深入了解装饰器的应用,包括日志记录、性能测量、事务处理等常见场景。此外,我们还将讨论装饰器的高级用法,如带参数的装饰器和类装饰器,为读者提供全面的装饰器使用指南。
|
2天前
|
存储 算法 搜索推荐
Python高手必备!揭秘图(Graph)的N种风骚表示法,让你的代码瞬间高大上
在Python中,图作为重要的数据结构,广泛应用于社交网络分析、路径查找等领域。本文介绍四种图的表示方法:邻接矩阵、邻接表、边列表和邻接集。每种方法都有其特点和适用场景,掌握它们能提升代码效率和可读性,让你在项目中脱颖而出。
13 5
|
2天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
11 4
|
3天前
|
缓存 开发者 Python
探索Python中的装饰器:简化和增强你的代码
【10月更文挑战第32天】 在编程的世界中,简洁和效率是永恒的追求。Python提供了一种强大工具——装饰器,它允许我们以声明式的方式修改函数的行为。本文将深入探讨装饰器的概念、用法及其在实际应用中的优势。通过实际代码示例,我们不仅理解装饰器的工作方式,还能学会如何自定义装饰器来满足特定需求。无论你是初学者还是有经验的开发者,这篇文章都将为你揭示装饰器的神秘面纱,并展示如何利用它们简化和增强你的代码库。
|
2天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
10 2
|
4天前
|
机器学习/深度学习 自然语言处理 API
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程
如何使用阿里云的语音合成服务(TTS)将文本转换为语音?本文详细介绍了从注册账号、获取密钥到编写Python代码调用TTS服务的全过程。通过简单的代码示例,展示如何将文本转换为自然流畅的语音,适用于有声阅读、智能客服等场景。
23 3
|
6天前
|
设计模式 缓存 测试技术
Python中的装饰器:功能增强与代码复用的艺术####
本文将深入探讨Python中装饰器的概念、用途及实现方式,通过实例演示其如何为函数或方法添加新功能而不影响原有代码结构,从而提升代码的可读性和可维护性。我们将从基础定义出发,逐步深入到高级应用,揭示装饰器在提高代码复用性方面的强大能力。 ####
|
4天前
|
算法 IDE API
Python编码规范与代码可读性提升策略####
本文探讨了Python编码规范的重要性,并深入分析了如何通过遵循PEP 8等标准来提高代码的可读性和可维护性。文章首先概述了Python编码规范的基本要求,包括命名约定、缩进风格、注释使用等,接着详细阐述了这些规范如何影响代码的理解和维护。此外,文章还提供了一些实用的技巧和建议,帮助开发者在日常开发中更好地应用这些规范,从而编写出更加清晰、简洁且易于理解的Python代码。 ####
|
7天前
|
缓存 测试技术 数据安全/隐私保护
探索Python中的装饰器:简化代码,增强功能
【10月更文挑战第29天】本文通过深入浅出的方式,探讨了Python装饰器的概念、使用场景和实现方法。文章不仅介绍了装饰器的基本知识,还通过实例展示了如何利用装饰器优化代码结构,提高代码的可读性和重用性。适合初学者和有一定经验的开发者阅读,旨在帮助读者更好地理解和应用装饰器,提升编程效率。
下一篇
无影云桌面