【Python办公自动化】遍历查询文件管理:os.walk/ os.scandir/ os.stat/ glob/ fnmatch/ Unix/ datetime

Python办公自动化 文件管理

  • 0 os 模块基础应用
  • 1 os.walk()
  • 2 os.scandir()
  • 3 os.stat()
  • 4 glob.glob()
  • 5 fnmatch.fnmatch()
  • 6 Unix 时间戳
    • 6.1 time.ctime()
    • 6.2 datetime.datetime.fromtimestamp()
    • 6.3 datetime.datetime.strftime()
  • 7 HomeWork 项目作业1
  • 8 HomeWork 项目作业 2
    • 8.1 方法1:os.walk() 遍历
    • 8.2 方法2:glob.glob() 遍历
    • 8.3 方法3:os.walk() + os.scandir()
    • 8.4 方法4:os.scandir() 递归遍历


转载请注明出处 !

手动反爬:【Python办公自动化】文件管理

https://blog.csdn.net/Lyun911/article/details/114227637

注:以下使用 VSCode 演示


0 os 模块基础应用

os.getcwd()# 获取当前地址
os.path.join('地址1', '地址2')# 生成地址
os.listdir()# 获取当前地址中的 文件列表


print(os.listdir())         # list
print(os.listdir('E:/dir1/dir2/'))   # 绝对路径
print(os.listdir('./'))     # 相对路径
# .startswith()
# .endswith()
# .replace()
# .upper()
# .lower()

1 os.walk()

遍历文件夹中的文件夹及文件,输出:文件位置/中的文件夹/中的文件

import os


for dirpath, dirnames, files in os.walk('./'):
# 写的时候都要同时取出三个元素 dirpath, dirnames, files 否则会有问题

print('-' * 50)
print(f'文件夹:{dirpath}')
print(f'中含文件夹:{dirnames}')
print(f'中包含文件:{files}')

2 os.scandir()

import os

for file in os.scandir():# os.scandir() 返回的内容是个迭代器
    print(file.name)        # 文件名:str
    print(file.is_dir())    # 是否文件夹:bool
    print(file.is_file())   # 是否文件:bool
    print(file.path)        # 文件路径+文件名:str
    print(file.is_symlink())# 是否符号链接:bool
    
    print(file.stat())          # 文件信息:
    print(file.stat().st_size)  # 文件的体积大小:int 单位:byte
    print(file.stat().st_atime) # 文件的最近访问时间:timestamp
    print(file.stat().st_mtime) # 文件的最近修改时间:timestamp
    print(file.stat().st_ctime) # Windows下表示创建时间:timestamp
    break
test.txt
False
True
.\test.txt
False
os.stat_result(st_mode=33206, st_ino=0, st_dev=0, st_nlink=0, st_uid=0, st_gid=0, st_size=857, st_atime=1614995201, st_mtime=1611481491, st_ctime=1611481491)
857
1614995201.2455294
1611481491.7471678
1611481491.7471678

3 os.stat()

import os

print(os.stat('a.txt'))
os.stat_result(
    st_mode=33206, st_ino=3377699720623040, st_dev=3028176084, 
    st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1614946104, 
    st_mtime=1614946104, st_ctime=1614946104)

4 glob.glob()

遍历文件夹中的文件,输出:文件路径+文件名 列表格式

import glob


# * 匹配所有字符
# ? 匹配任意单个字符
# [seq] 匹配seq中的任何字符
# [!seq] 匹配任何不在seq中的字符
print(glob.glob('whatever*.py'))
print(glob.glob('whatever?.py'))
print(glob.glob('whatever[0-9].py'))
print(glob.glob('whatever[1, 3, 5].py'))
print(glob.glob('whatever[!1, 3, 5].py'))

# ** 表示任意层文件或文件夹
# recursive = True 会不断进入文件夹内(recursive 递归)
# 输出的结果为 路径+文件名
print(glob.glob('**/*.pdf', recursive = True))

# 遍历查询文件夹中文件名称 开头非数字,且结尾为英文字幕 的文件
print(glob.glob('[!0-1]*[a-zA-Z].*'), recursive = True)

5 fnmatch.fnmatch()

# 检查参数1是否符合参数2的规则
import fnmatch

print(fnmatch.fnmatch('whatever.py', 'wha*r.py'))
print(fnmatch.fnmatch('whatever.py', 'wha*[0-9]r.py'))

6 Unix 时间戳

6.1 time.ctime()

将 timestamp 格式转化为正常的时间:

# time.ctime()
import time
print(time.ctime(1565565545))# >>> Mon Aug 12 07:19:05 2019

6.2 datetime.datetime.fromtimestamp()

用 datetime.datetime() 提取 timestamp() 中的时间

import datetime

t = datetime.datetime.fromtimestamp(1614956371)

print(t)# 2021-03-05 22:59:31
print(t.year, t.month, t.day, t.hour, t.minute, t.second)# 2021 3 5 22 59 31

6.3 datetime.datetime.strftime()

from datetime import datetime

now = datetime.now()# current date and time

year = now.strftime("%Y")# 2021
month = now.strftime("%m")# 03
day = now.strftime("%d")# 05
time = now.strftime("%H:%M:%S")# 23:08:47
date_time = now.strftime("%Y-%m-%d, %H:%M:%S")# 2021-03-05, 23:08:47
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身

7 HomeWork 项目作业1

# 编写一个Python程序,要求
# 1.找出当前目录下所有非文件夹的文件
# 2.统计其中包含有“Python”单词的文件数量
# 3.不区分大小写,即大写和小写都包括在内
# 4.输出文件数量
import os

counter = 0
for f in os.scandir():
    if not f.is_dir():
        if 'a' in f.name.lower():
            counter += 1
            print(f.name)
print(f'含有 "a" 的文件一共有 {counter:^2} 个')

8 HomeWork 项目作业 2

# 编写一个Python程序,要求
# 1.搜索整个文件夹,包括文件夹内的所有文件夹
# 2.筛选体积大于1MB的.pdf文件
# 3.筛选这些文件中日期早于2021年之前的文件
# 4.输出这些文件的路径
春节的时候没事干
在家里琢磨琢磨写了4种方法以供参考
如果写的有什么纰漏可以在文下提出 :D

8.1 方法1:os.walk() 遍历

import os
import datetime


for dirpath, dirnames, files in os.walk(os.getcwd()):
# 如果 os.getcwd()绝对地址 改为 './'相对地址也可以
    print('----------')
    for f in files:
        f_stat = os.stat(dirpath + '/' + f)
        f_mtime = datetime.datetime.fromtimestamp(f_stat.st_mtime)
        f_size = f_stat.st_size / 1024 / 1024
        if f.endswith('.pdf') and (f_size >= 0.1) and (f_mtime.year <= 2021):
            print(f'文件地址:{dirpath} | 文件名:{f} | 文件大小MB:{f_size:.2f}MB | 最后修改日期:{f_mtime.date()}')

8.2 方法2:glob.glob() 遍历

import os
import datetime
import glob


for f in glob.glob('**/*.pdf', recursive = True):
    f_stat = os.stat(f)
    f_name = f.split('\\')[-1]
    f_dir = f[:len(f) - len(f_name)]
    f_mtime = datetime.datetime.fromtimestamp(f_stat.st_mtime)
    f_size = f_stat.st_size / 1024 / 1024
    if f_name.endswith('.pdf') and (f_size >= 0.1) and (f_mtime.year <= 2021):
        print(f'文件地址:{f_dir} | 文件名:{f_name} | 文件大小MB:{f_size:.2f}MB | 最后修改日期:{f_mtime.date()}')

# glob.glob() 函数里面加上 recursive = True 才可以实现遍历查询
# 切割的时候用 f.split 还挺方便的,直接从 f 中可以找到文件名

8.3 方法3:os.walk() + os.scandir()

import os
from datetime import datetime


for dirpath, dirnames, files in os.walk('./'):
    for f in os.scandir(dirpath):
        if f.is_file():
            f_stat = f.stat()
            f_mtime = datetime.fromtimestamp(f_stat.st_mtime)
            f_size = f_stat.st_size / 1024 / 1024
            if f.name.endswith('.pdf') and (f_size >= 0.1) and (f_mtime.year <= 2021):
                print(f'文件地址:{dirpath} | 文件名:{f} | 文件大小MB:{f_size:.2f}MB | 最后修改日期:{f_mtime.date()}')

8.4 方法4:os.scandir() 递归遍历

import os
import datetime


def file_stats(path_ = os.getcwd()):
    print('----------')
    for f in os.scandir(path_):
        if f.is_file():
            f_size = f.stat().st_size / 1024 / 1024
            f_mtime = datetime.datetime.fromtimestamp(f.stat().st_mtime)
            f_dir = f.path[:len(f.path) - len(f.name)]
            if f.name.endswith('.pdf') and f_size >= 0.1 and f_mtime.year <= 2021:
                print(f'文件地址:{f_dir} | 文件名:{f.name} | 文件大小MB:{f_size:.2f}MB | 最后修改日期:{f_mtime.date()}')
        else:
            file_stats(f)

file_stats()
# 方法总结:

# os.scandir() 的返回结果其实是一个  迭代器
# os.scandir() 里面包含了一些 函数/属性,比如 for f in os.scandir():
#     f.is_dir()
#     f.is_file()
#     f.stat()
#     f.path
#     f.name
# 这里面的 path 只包含了 路径+文件名,所以单纯的路径只能从 f.path 中切片提取

# os.scandir() 本身并不能迭代,所以我把主程序部分设计成了递归(recursive),这样就可以实现遍历了

# f.st_mtime 要经过 datetime.datetime.fromtimestamp() 加工之后才好使用
# 并且,加工后的 f_mtime 有一些 方法/属性 很好用,比如:
#     f_mtime.date()
#     f_mtime.year
#     f_mtime.month
#     f_mtime.day
#     f_mtime.minute
#     etc.

# .endswith() 也可以改成 [-4:] 这样写还更简洁一些

你可能感兴趣的:(Python基础,python)