批量获取百度网盘文件目录
当网盘文件超过100G的时候,找文件就有点苦恼了,不记得放在什么文件夹,也不记得名字,就想着从目录着手。
现在百度网盘还未推出目录功能,这里就套用网上推荐的查询目录的方式。后面附有代码。
整体思路
查看网盘缓存数据库文件
百度网盘在本地有个数据库文件BaiduYunCacheFileV0.db
,里面存放着文件路径和文件名等信息,两者结合提取出目录信息。该文件可以用Navicat Premium 15打开。
代码分析
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename
from tkinter.ttk import *
import sqlite3
这里用到了用于GUI图形界面开发的库,Tkinter 模块(Tk 接口),其中Tkinter filedialog是文件对话框控件。由于tkinter模块下的组件,整体风格较老较丑,同时也导入了组件更加美观、功能更加强大的ttk 组件。ttk新增了 LabeledScale( 带标签的Scale)、Notebook( 多文档窗口)、Progressbar(进度条)、Treeview(数)等组件。
def select_db_file():
db_file = askopenfilename(title="请选择BaiduYunCacheFileV0.db文件",filetypes=[('db', '*.db')])
db.set(db_file)
def select_save_file():
save_file = asksaveasfilename(filetypes=[('文件', '*.txt')])
f.set(save_file+".txt")
StringVar的作用,我们在使用界面编程的时候,有些时候是需要跟踪变量的值的变化,以保证值的变更随时可以显示在界面上。由于python无法做到这一点,所以使用了tcl的相应的对象,也就是StringVar、BooleanVar、DoubleVar、IntVar
- StringVar类型需要通过
StringVar.set()
写入string字符串内容。 - StringVar类型需要通过
StringVar.get()
读取内容,返回一个string字符串
askopenfilename
返回文件名,是string字符串类型
select_db_file()
函数巧妙的是,它把StringVar变量的声明写在了函数的外面且后面出现,而不是函数内部,呀呀,就是不能写在函数内部,在函数外面才是全局变量。
当然也可以理解为回调函数,当按钮被点击时,变量就存在了,不用担心它声明在后面
核心函数
def write_file(file_dict,f,item,gap=""):
if item=="/":
f.write("━" + "/" + "\n")
for i in file_dict["/"]:
f.write("┣" + "━" + i + "\n")
i = item + i + "/"
if i in file_dict:
write_file(file_dict,f,i, gap="┣━")
else:
gap = "┃ " + gap
for i in file_dict[item]:
f.write(gap + i + "\n")
i = item + i + "/"
if i in file_dict:
write_file(file_dict,f,i,gap)
递归函数write_file(file_dict,f,item,gap="")
,参数分别是存放路径和对应文件的字典file_dict
,f是待写入内容的txt文件,item是路径,gap是间隙
函数主体分析:如果路径item是最外层的路径,就将最外层路径对应的文件名,写入到f文件中,然后根据文件名重新赋值一个新路径,判断这个新路径是否在字典中,如果在,就递归调用该函数,检查文件名是否是文件夹(也就是文件名包装后的新路径在字典中)
如果路径不是根路径,每次调用函数gap会变化,将新路径对应的文件名,写入到f文件中,然后在文件名前面加上上一级路径后面加上/,赋值一个新路径,在字典中检查,也就是判断该文件名变成路径后,是否还有下一级路径,如果字典中有它
就表示有下一级路径,然后继续调用该函数。
连接数据库提取内容
def create_baiduyun_filelist():
file_dict = {}
conn = sqlite3.connect(db.get())
cursor = conn.cursor()
cursor.execute("select * from cache_file")
while True:
value = cursor.fetchone()
if not value:
break
path = value[2]
name = value[3]
size = value[4]
isdir = value[6]
if path not in file_dict:
file_dict[path] = []
file_dict[path].append(name)
else:
file_dict[path].append(name)
with open(f.get(),"w",encoding='utf-8') as fp:
write_file(file_dict,fp,"/")
conn.close()
conn = sqlite3.connect(db.get())
连接数据库,db是StringVar类型,需要通过db.get()
读取db里的内容,返回string类型的字符串,这里是地址+数据库文件名
cursor = conn.cursor()
使用 cursor() 方法创建一个游标对象,游标对象用于执行查询和获取结果
cursor.execute("select * from cache_file")
使用 execute() 方法执行 SQL 查询,SQL语句和BaiduYunCacheFileV0.db
里的表格结构有关系,它里面有张叫cache_file
的表
value = cursor.fetchone()
fetchone() 获取下一个查询结果集。结果集是一个对象
conn.close()
关闭数据库连接
主函数
root = Tk()
root.title('百度云文件列表生成工具')
db_select = Button(root, text=' 选择DB文件 ',command=select_db_file)
db_select.grid(row=1,column=1,sticky=W,padx=(2,0),pady=(2,0))
db = StringVar()
db_path = Entry(root,width=80,textvariable = db)
db_path['state'] = 'readonly'
db_path.grid(row=1,column=2,padx=3,pady=3,sticky=W+E)
save_path = Button(root, text='选择保存地址',command=select_save_file)
save_path.grid(row=2,column=1,sticky=W,padx=(2,0),pady=(2,0))
f = StringVar()
file_path = Entry(root,width=80,textvariable = f)
file_path['state'] = 'readonly'
file_path.grid(row=2, column=2,padx=3,pady=3,sticky=W+E)
create_btn = Button(root, text='生成文件列表',command=create_baiduyun_filelist)
create_btn.grid(row=3,column=1,columnspan=2,pady=(0,2))
root.columnconfigure(2, weight=1)
root.mainloop()
root = Tk()
调用窗口函数,实例化一个窗口对象
root.title('百度云文件列表生成工具')
窗口最顶部显示的文字
db_select = Button(root, text=' 选择DB文件 ',command=select_db_file)
在窗口上创建一个button,调用一个按钮,command代表点击按钮发生的事件
padx,pady:与之并列的组件之间的间隔,x方向和y方向,默认单位是像素
db_select.grid(row=1,column=1,sticky=W,padx=(2,0),pady=(2,0))
设置按钮的位置,在第一行第一列,padx=(2,0) ,与之并列的组件之间的间隔,水平方向上,button与左边的组件,距离是2个像素,与右边的组件,距离是0像素。
如果不调用Button的grid函数,它将不会显示。sticky=W靠左边。
sticky:有点类似于 pack() 方法的 anchor 选项,同样支持 N(北,代表上)、E(东,代表右)、S(南,代表下)、W(西,代表左)、NW(西北,代表左上)、NE(东北,代表右上)、SW(西南,代表左下)、SE(东南,代表右下)、CENTER(中,默认值)这些值。
db = StringVar()
StringVar是Tk库内部定义的字符串变量类型,改变StringVar,按钮上的文字也随之改变。
db_path = Entry(root,width=80,textvariable = db)
TKinter输入类(TKinter文本框)获取用户输入,TKinter Entry类创建文本框,把变量db绑定到Entry
db_path['state'] = 'readonly'
变量db绑定Entry后,Entry状态变为只读
root.columnconfigure(2, weight=1)
列属性设置
root.mainloop()
此函数调用窗口的无限循环,因此窗口将等待任何用户交互,直到我们将其关闭。
grid()方法相关参数
选项 | 说明 | 取值范围 |
---|---|---|
column | 单元格的列号 | 从0开始的正整数column |
columnspan | 跨列,跨越的列数 | 正整数 |
row | 单元格的行号 | 从0开始的正整数 |
rowspan | 跨行,跨越的行数 | 正整数 |
ipadx, ipady | 设置子组件之间的间隔,x方向或者y方向,默认单位为像素 | 非负浮点数,默认0.0 |
padx,pady | 与之并列的组件之间的间隔,x方向或者y方向,默认单位是像素 | 非负浮点数,默认0.0 |
sticky | 组件紧贴所在单元格的某一角,对应于东南西北中以及4个角 | N/S/W/E, NW/SW/SE/NE, CENTER(默认) |
整体代码
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from tkinter import *
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename
from tkinter.ttk import *
import sqlite3
def select_db_file():
db_file = askopenfilename(title="请选择BaiduYunCacheFileV0.db文件",filetypes=[('db', '*.db')])
db.set(db_file)
def select_save_file():
save_file = asksaveasfilename(filetypes=[('文件', '*.txt')])
f.set(save_file+".txt")
def write_file(file_dict,f,item,gap=""):
if item=="/":
f.write("━" + "/" + "\n")
for i in file_dict["/"]:
f.write("┣" + "━" + i + "\n")
i = item + i + "/"
if i in file_dict:
write_file(file_dict,f,i, gap="┣━")
else:
gap = "┃ " + gap
for i in file_dict[item]:
f.write(gap + i + "\n")
i = item + i + "/"
if i in file_dict:
write_file(file_dict,f,i,gap)
def create_baiduyun_filelist():
file_dict = {}
conn = sqlite3.connect(db.get())
cursor = conn.cursor()
cursor.execute("select * from cache_file")
while True:
value = cursor.fetchone()
if not value:
break
path = value[2]
name = value[3]
size = value[4]
isdir = value[6]
if path not in file_dict:
file_dict[path] = []
file_dict[path].append(name)
else:
file_dict[path].append(name)
with open(f.get(),"w",encoding='utf-8') as fp:
write_file(file_dict,fp,"/")
conn.close()
root = Tk()
root.title('百度云文件列表生成工具')
db_select = Button(root, text=' 选择DB文件 ',command=select_db_file)
db_select.grid(row=1,column=1,sticky=W,padx=(2,0),pady=(2,0))
db = StringVar()
db_path = Entry(root,width=80,textvariable = db)
db_path['state'] = 'readonly'
db_path.grid(row=1,column=2,padx=3,pady=3,sticky=W+E)
save_path = Button(root, text='选择保存地址',command=select_save_file)
save_path.grid(row=2,column=1,sticky=W,padx=(2,0),pady=(2,0))
f = StringVar()
file_path = Entry(root,width=80,textvariable = f)
file_path['state'] = 'readonly'
file_path.grid(row=2, column=2,padx=3,pady=3,sticky=W+E)
create_btn = Button(root, text='生成文件列表',command=create_baiduyun_filelist)
create_btn.grid(row=3,column=1,columnspan=2,pady=(0,2))
root.columnconfigure(2, weight=1)
root.mainloop()
运行结果
参考资料:
Python官方手册:https://docs.python.org/zh-cn/3.8/library/tkinter.ttk.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本