优先用path.iterdir()安全遍历下载目录,它自动跳过.和..,返回path对象便于类型判断;需过滤隐藏文件、跳过下载中文件(ctime==mtime)、按小写后缀精准归类,移动前检查重名并处理只读属性。

用 os.listdir() 和 pathlib.Path 安全遍历下载目录
直接 os.listdir() 读取可能遇到权限错误或符号链接循环,pathlib.Path 更健壮。优先用 Path.iterdir(),它跳过当前目录(.)和父目录(..),且返回 Path 对象便于后续判断类型。
- 避免用
os.walk()—— 下载文件夹通常无子目录,递归反而增加误操作风险 - 过滤掉隐藏文件:检查
file.name.startswith('.'),比如.DS_Store或临时下载碎片xxx.part - 跳过正在被写入的文件:用
file.stat().st_ctime == file.stat().st_mtime粗略判断(刚创建就修改过,大概率还在下载中)
按文件扩展名精准归类到目标子目录
别依赖 MIME 类型——浏览器下载的 .xlsx 可能被识别成 application/octet-stream,扩展名才是最可靠依据。但注意大小写:.PDF 和 .pdf 要统一转小写再匹配。
- 常见分类规则示例:
rules = { 'pdf': 'Documents', 'jpg jpeg png gif': 'Images', 'mp4 mov avi': 'Videos', 'zip rar 7z': 'Archives', 'py js ts html': 'Code', 'exe msi pkg': 'Installers' } - 用
file.suffix.lower().strip('.') in extensions_set查找,比str.endswith()更准(避免.tar.gz被误判为gz) - 未匹配的文件暂移至
Others,不要直接删除
移动文件时处理重名、只读、跨分区等真实问题
shutil.move() 在同分区是原子重命名,跨分区才真正复制+删除;但若目标已存在同名文件,它会直接覆盖——这很危险。
- 先用
target.exists()检查,存在则生成新名:target.with_name(f"{target.stem}_1{target.suffix}") - Windows 上下载的
.exe常带只读属性,移动前加file.chmod(0o644) - 遇到
PermissionError: [WinError 5],通常是杀软锁定了文件,跳过并记录日志即可,别硬 retry
加个简单配置文件让规则可维护
把分类规则写死在代码里,下次想加 .epub 就得改 Python 文件——用 config.json 分离逻辑和数据更稳妥。
- 配置结构示例:
{ "download_dir": "/Users/me/Downloads", "archive_old_files": true, "age_threshold_days": 1, "categories": { "Documents": ["pdf", "docx", "txt"], "Images": ["jpg", "png"] } } - 读取时用
json.load(),但注意路径必须是绝对路径,相对路径容易因执行位置不同出错 - 首次运行时自动创建配置模板,比报错提示 “请先写 config.json” 更友好
image(无后缀)或迅雷的 .tdownload。这类得单独列进规则,或者加个「手动检查队列」机制——自动化不是为了消灭人工,而是把人从重复劳动里解放出来做判断。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











