批量获取百度网盘文件目录


当网盘文件超过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官方手册

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值