Python办公14:批量解压文件夹内的所有 ZIP/RAR 并自动分类

14:压缩包处理------批量解压文件夹内的所有 ZIP/RAR 并自动分类

第二阶段:文件管理与系统自动化(9-15)

场景引入

收到同事发来的 30 个 ZIP 压缩包,每个都要手动右键 → 解压到此处 → 整理文件。如果遇到 RAR 格式,Windows 自带的解压还不支持,要装第三方软件。

本节用 Python 实现一键批量解压,自动创建对应文件夹,并分类管理。


技术原理

压缩格式 Python 库 说明
ZIP zipfile(内置) 原生支持
RAR rarfile 需安装 + 配置 unrar
TAR/GZ tarfile(内置) 原生支持
7Z py7zr 需安装
复制代码
目录中的所有压缩包
  ↓ 逐个检测格式
ZIP → zipfile 解压
RAR → rarfile 解压
  ↓ 创建同名文件夹
解压内容放入 文件名/ 目录
  ↓ 分类管理
按文件类型归类解压后的文件

环境准备

bash 复制代码
# ZIP/TAR 使用内置库,无需安装
pip install rarfile py7zr

RAR 解压还需要安装 UnRAR 程序(Windows 可从 https://www.rarlab.com/rar_add.htm 下载)。


完整代码

python 复制代码
import os
import zipfile
import tarfile
from pathlib import Path
from datetime import datetime

# ==================== ZIP 解压 ====================
def extract_zip(zip_path, extract_dir=None):
    """
    解压 ZIP 文件

    参数:
        zip_path: ZIP 文件路径
        extract_dir: 解压目录(默认在 ZIP 同级目录创建同名文件夹)
    """
    zip_file = Path(zip_path)
    if extract_dir is None:
        extract_dir = zip_file.parent / zip_file.stem

    extract_dir.mkdir(parents=True, exist_ok=True)

    with zipfile.ZipFile(zip_file, 'r') as zf:
        # 检查是否有密码
        has_password = any(zinfo.flag_bits & 0x1 for zinfo in zf.infolist())

        if has_password:
            password = input(f"请输入 {zip_file.name} 的密码: ").encode()
        else:
            password = None

        zf.extractall(extract_dir, pwd=password)

    print(f"[ZIP解压] {zip_file.name} → {extract_dir}/")
    return extract_dir


# ==================== TAR/GZ 解压 ====================
def extract_tar(tar_path, extract_dir=None):
    """解压 TAR/TAR.GZ/TAR.BZ2 文件"""
    tar_file = Path(tar_path)
    if extract_dir is None:
        extract_dir = tar_file.parent / tar_file.stem

    extract_dir.mkdir(parents=True, exist_ok=True)

    # 自动检测压缩类型
    mode = 'r:*'  # 自动检测
    with tarfile.open(tar_file, mode) as tf:
        tf.extractall(extract_dir)

    print(f"[TAR解压] {tar_file.name} → {extract_dir}/")
    return extract_dir


# ==================== 批量解压 ====================
def batch_extract_all(search_dir, extract_base=None):
    """
    批量解压目录中的所有压缩包

    参数:
        search_dir: 包含压缩包的目录
        extract_base: 解压根目录(默认在源目录下创建"已解压"文件夹)
    """
    search_path = Path(search_dir)

    if extract_base is None:
        extract_base = search_path / "已解压"
    extract_base.mkdir(parents=True, exist_ok=True)

    stats = {'success': 0, 'failed': 0, 'skipped': 0}

    for file_path in search_path.rglob('*'):
        if not file_path.is_file():
            continue

        suffix = file_path.suffix.lower()
        extract_dir = extract_base / file_path.stem

        # 跳过已经解压过的
        if extract_dir.exists() and any(extract_dir.iterdir()):
            stats['skipped'] += 1
            continue

        try:
            if suffix == '.zip':
                extract_zip(file_path, extract_dir)
                stats['success'] += 1

            elif suffix in ('.tar', '.gz', '.bz2', '.tgz'):
                extract_tar(file_path, extract_dir)
                stats['success'] += 1

            elif suffix == '.rar':
                try:
                    import rarfile
                    with rarfile.RarFile(file_path, 'r') as rf:
                        extract_dir.mkdir(parents=True, exist_ok=True)
                        rf.extractall(extract_dir)
                    print(f"[RAR解压] {file_path.name} → {extract_dir}/")
                    stats['success'] += 1
                except ImportError:
                    print(f"[跳过] {file_path.name}: 需要安装 rarfile 库")
                    stats['failed'] += 1

            elif suffix == '.7z':
                try:
                    import py7zr
                    with py7zr.SevenZipFile(file_path, 'r') as sz:
                        extract_dir.mkdir(parents=True, exist_ok=True)
                        sz.extractall(extract_dir)
                    print(f"[7Z解压] {file_path.name} → {extract_dir}/")
                    stats['success'] += 1
                except ImportError:
                    print(f"[跳过] {file_path.name}: 需要安装 py7zr 库")
                    stats['failed'] += 1

        except Exception as e:
            print(f"[失败] {file_path.name}: {e}")
            stats['failed'] += 1

    # 汇总
    print(f"\n{'='*50}")
    print(f"批量解压完成!")
    print(f"成功: {stats['success']}")
    print(f"失败: {stats['failed']}")
    print(f"跳过: {stats['skipped']}")


# ==================== 解压后文件分类 ====================
def classify_extracted_files(extract_dir):
    """
    对解压后的文件按类型分类整理
    """
    from shutil import move

    CLASSIFY_RULES = {
        '.jpg': '图片', '.jpeg': '图片', '.png': '图片', '.gif': '图片',
        '.doc': '文档', '.docx': '文档', '.pdf': '文档', '.txt': '文档',
        '.xls': '表格', '.xlsx': '表格', '.csv': '表格',
        '.mp4': '视频', '.avi': '视频', '.mkv': '视频',
        '.mp3': '音频', '.wav': '音频',
    }

    extract_path = Path(extract_dir)

    for file_path in extract_path.rglob('*'):
        if file_path.is_file():
            suffix = file_path.suffix.lower()
            category = CLASSIFY_RULES.get(suffix)

            if category:
                category_dir = extract_path / category
                category_dir.mkdir(exist_ok=True)

                dest = category_dir / file_path.name
                if not dest.exists():
                    move(str(file_path), str(dest))

    print(f"文件分类完成: {extract_dir}/")


# ==================== 使用示例 ====================
if __name__ == "__main__":
    # 批量解压
    batch_extract_all(r"D:\Downloads\压缩包")

    # 分类解压后的文件
    # classify_extracted_files(r"D:\Downloads\压缩包\已解压")

常见问题

Q1:RAR 解压报错 RarCannotExec: Cannot find unpacked unrar

需要安装 UnRAR 可执行文件:

  1. 下载:https://www.rarlab.com/rar_add.htm
  2. UnRAR.exe 放到系统 PATH 中,或指定路径:
python 复制代码
import rarfile
rarfile.UNRAR_TOOL = r"C:\Program Files\WinRAR\UnRAR.exe"

Q2:加密 ZIP 怎么办?

代码已自动检测密码文件。也可以手动指定:

python 复制代码
zf.extractall(extract_dir, pwd=b'your_password')

Q3:解压路径过长导致失败?

Windows 路径最大长度为 260 字符。可以:

  1. 解压到更短的路径(如 D:\tmp\
  2. 或在注册表中启用长路径支持

总结

格式 解压函数
ZIP zipfile(内置) ZipFile.extractall()
RAR rarfile RarFile.extractall()
TAR tarfile(内置) TarFile.extractall()
7Z py7zr SevenZipFile.extractall()

本节掌握了批量解压各种格式压缩包的能力。

下一节预告:15:Windows 注册表优化------通过 Python 脚本一键开关系统特效!

相关推荐
郑州光合科技余经理1 小时前
海外版外卖系统架构:订单怎么流转、权限怎么分
java·开发语言·前端·系统架构·uni-app·php·ai编程
Python 实战手记1 小时前
企业微信主体变更公证书办理全解析:适用场景、材料规范、踩坑点与Python信息校验脚本
开发语言·python·企业微信
longxiaozhang61 小时前
C#异常处理:程序出错了怎么办?
开发语言·数据库·c#
郝学胜_神的一滴1 小时前
Effective Python 条款 2:遵循 PEP 8 编码风格,写出高质量 Python 代码
python·算法
郝学胜-神的一滴1 小时前
Effective Python 条款 1:确认你正在使用的 Python 版本
开发语言·数据结构·python·程序人生·算法
RanMatrix1 小时前
Python列表精讲
python
一入程序无退路1 小时前
Navicat导出Excel格式表名表结构
数据库·excel
路多辛1 小时前
全能型 Go Agent 框架 covonaut v1.0.8 发布:新增行内补全与多后端可观测性
开发语言·golang·agent
大模型丫丫1 小时前
FastAPI 入门指南:从零开始构建高性能 Python API
开发语言·python·fastapi