ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-07-13 19:33:33  阅读:358  来源: 互联网

标签:文件目录 百度网 批量 db dict file path root select


目录

当网盘文件超过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

标签:文件目录,百度网,批量,db,dict,file,path,root,select
来源: https://www.cnblogs.com/fylhd2013/p/15006636.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有