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

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS Agent(兼容Hermes Agent),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')


搞定。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
8月前
|
测试技术 Python
Python装饰器:为你的代码施展“魔法”
Python装饰器:为你的代码施展“魔法”
389 100
|
8月前
|
开发者 Python
Python列表推导式:一行代码的艺术与力量
Python列表推导式:一行代码的艺术与力量
589 95
|
8月前
|
缓存 Python
Python装饰器:为你的代码施展“魔法
Python装饰器:为你的代码施展“魔法
501 88
|
8月前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。
1471 68
|
9月前
|
开发者 Python
Python神技:用列表推导式让你的代码更优雅
Python神技:用列表推导式让你的代码更优雅
688 99
|
9月前
|
Python
Python的简洁之道:5个让代码更优雅的技巧
Python的简洁之道:5个让代码更优雅的技巧
394 104
|
9月前
|
设计模式 人工智能 API
AI智能体开发实战:17种核心架构模式详解与Python代码实现
本文系统解析17种智能体架构设计模式,涵盖多智能体协作、思维树、反思优化与工具调用等核心范式,结合LangChain与LangGraph实现代码工作流,并通过真实案例验证效果,助力构建高效AI系统。
1016 7
|
9月前
|
JSON 缓存 开发者
淘宝商品详情接口(item_get)企业级全解析:参数配置、签名机制与 Python 代码实战
本文详解淘宝开放平台taobao.item_get接口对接全流程,涵盖参数配置、MD5签名生成、Python企业级代码实现及高频问题排查,提供可落地的实战方案,助你高效稳定获取商品数据。
|
9月前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
442 26
|
9月前
|
存储 大数据 Unix
Python生成器 vs 迭代器:从内存到代码的深度解析
在Python中,处理大数据或无限序列时,迭代器与生成器可避免内存溢出。迭代器通过`__iter__`和`__next__`手动实现,控制灵活;生成器用`yield`自动实现,代码简洁、内存高效。生成器适合大文件读取、惰性计算等场景,是性能优化的关键工具。
444 2

推荐镜像

更多