基于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盘文件随着新建、剪切、移动、粘贴后再去进行检索,搜索结果也就不会精确。
脆弱的代码,并没有闭环,没有闭环就没有生命更不会存在灵魂!
不能够与真正的搜索引擎一样随着大量数据没日没夜的新增,实时的爬取与更新。
我们可以尝试封装,或者计划任务进行定时执行,当然你不会感觉枯燥可以尝试针对全系统的文件检测,或者循环已有索引进行检测。