Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

基于Python,构建本地搜索引擎

基于Python构建电脑本地盘的搜索示例​

第一种方法是遍历需要检索指定区域所有文件,如果电脑配置不是很好,会影响效率​。

第二种方式是考虑建立索引,在用户点击搜索时,通过索引列表来达到快速搜索。

我们首先考虑怎么构建一个本地盘文件的索引表​;

import os
import json

def build_index(path):
    index = []
    for root, dirs, files in os.walk(path):
        for file in files:
            file_path = os.path.join(root, file)
            index.append({"name": file, "path": file_path})
    return index

# 设置要索引的路径
path_to_index = 'D:\\'
# 构建索引
index = build_index(path_to_index)

# 设置存储索引的文件路径
index_file_path = 'D:\\daku\\搜索\\index.json'

# 将索引列表以JSON格式写入文件
with open(index_file_path, 'w', encoding='utf-8') as index_file:
    json.dump(index, index_file, ensure_ascii=False, indent=4)

print(f"Index has been saved to {index_file_path}")

以此代码将D盘全局索引以json格式存入指定位置。

索引文件大小为36.5M

然后需要构建主窗口,搜索框,搜索按钮,以及显示框​。

import tkinter as tk
from tkinter import filedialog, messagebox
import json
import os
from threading import Thread


class SearchApp:
    def __init__(self, root):
        self.root = root
        self.root.title("本地检索")
        self.root.geometry("1500x800")

        # 创建搜索框和搜索按钮
        self.search_entry = tk.Entry(root, font=("Arial", 12))
        self.search_entry.pack(pady=10)

        self.search_button = tk.Button(root, text="搜索", command=self.start_search, bg="purple", fg="white")
        self.search_button.pack(pady=10)

        # 绑定回车键到搜索按钮
        self.root.bind("<Return>", lambda e: self.start_search())

        # 创建搜索结果列表
        self.result_listbox = tk.Listbox(root, height=30, width=120)
        self.result_listbox.pack(pady=10)

        # 绑定双击事件到打开文件或文件夹
        self.result_listbox.bind("<Double-1>", self.open_item)

        # 进度显示
        self.progress_label = tk.Label(root, text="", fg="gray")
        self.progress_label.pack(pady=10)

        # 搜索线程和状态
        self.search_thread = None

    def start_search(self):
        if self.search_thread is not None and self.search_thread.is_alive():
            messagebox.showwarning("警告", "搜索正在进行中,请稍候!")
            return

        keyword = self.search_entry.get()
        if not keyword:
            messagebox.showwarning("警告", "请输入搜索关键词!")
            return

        self.progress_label.config(text="搜索中...")
        self.result_listbox.delete(0, tk.END)

        self.search_thread = Thread(target=self.do_search, args=(keyword,))
        self.search_thread.start()

    def do_search(self, keyword):
        try:
            with open(r"D:\daku\搜索\index.json", "r", encoding="utf-8") as file:
                data = json.load(file)

            files_found = []
            for item in data:
                if keyword.lower() in item["name"].lower():  # 修改为正确的键名 "name"
                    files_found.append(item)
                    self.update_progress(len(files_found))

                    # 更新GUI以显示结果
            self.root.after(100, self.update_gui_with_results, files_found)

        except FileNotFoundError:
            self.root.after(100, lambda: messagebox.showerror("错误", "未找到索引文件。"))
        except Exception as e:
            self.root.after(100, lambda e=e: messagebox.showerror("错误", str(e)))

    def update_progress(self, count):
        self.root.after(100, lambda: self.progress_label.config(text=f"已搜索到 {count} 个文件..."))

    def update_gui_with_results(self, files_found):
        if self.search_thread.is_alive():
            return  # 防止在结果还在被修改时更新GUI

        self.progress_label.config(text="")
        for file in files_found:
            self.result_listbox.insert(tk.END, f"{file['name']} - {file['path']}")  # 修改为正确的键名 "name"

        if files_found:
            self.progress_label.config(text=f"搜索完成,找到 {len(files_found)} 个文件。")

    def open_item(self, event):
        selected = self.result_listbox.curselection()
        if not selected:
            return

        index = selected[0]
        data = self.result_listbox.get(index).split(" - ")
        filename = data[0]
        filepath = data[1]

        # 检查文件是否存在
        if os.path.exists(filepath):
            # 如果是文件,则尝试打开
            if os.path.isfile(filepath):
                os.startfile(filepath)
            # 如果是目录,则尝试打开目录
            elif os.path.isdir(filepath):
                os.startfile(filepath, 'open')
        else:
            messagebox.showerror("错误", "文件或目录不存在。")


# 创建Tk窗口并运行应用
root = tk.Tk()
app = SearchApp(root)
root.mainloop()

有没有发现什么问题呢​?

如果我们D盘文件随着新建、剪切、移动、粘贴后再去进行检索,搜索结果也就不会精确​。

脆弱的代码,并没有闭环,没有闭环就没有生命更不会存在灵魂​!

不能够与真正的搜索引擎一样随着大量数据没日没夜的新增,实时的爬取与更新​。

我们可以尝试封装,或者计划任务进行定时执行,当然你不会感觉枯燥可以尝试针对全系统的文件检测,或者循环已有索引进行检测​。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值