我的知识记录

Python解压zip压缩包教程:一行代码完整提取

用Python标准库zipfile解压zip压缩包到指定目录,支持覆盖、密码解压、中文文件名处理,完整可运行示例代码。

场景痛点

收到一个几百MB的zip压缩包,手动右键解压要等进度条,遇到带密码的包还得每次输入密码。如果要解压多个包到不同目录,反复点击鼠标很机械。用Python脚本把解压动作固化下来,指定输入包和输出目录,跑一次就完事,还能顺便校验文件数量。

用到的库

zipfile   # 标准库,读写zip
pathlib   # 标准库,路径处理

完整代码

import zipfile
from pathlib import Path


def extract_zip(zip_path: str, dest_dir: str, password: str = None, overwrite: bool = True) -> int:
"""
解压zip文件到指定目录
:param zip_path: zip文件路径
:param dest_dir: 解压目标目录
:param password: 解压密码,无密码传None
:param overwrite: 是否覆盖已存在的文件
:return: 解压出的文件数
"""
zpath = Path(zip_path)
dest = Path(dest_dir)
dest.mkdir(parents=True, exist_ok=True)

count = 0
with zipfile.ZipFile(zpath, 'r') as zf:
# 设置密码(如果有)
pwd = password.encode('utf-8') if password else None
for member in zf.namelist():
# 计算目标文件绝对路径
target = (dest / member).resolve()
# 安全校验:防止zip slip路径穿越攻击
if not str(target).startswith(str(dest.resolve())):
print(f"跳过不安全路径: {member}")
continue
if target.exists() and not overwrite:
continue
zf.extract(member, dest, pwd=pwd)
count += 1

print(f"解压完成 -> {dest.resolve()},共 {count} 个条目")
return count


if __name__ == "__main__":
extract_zip(
zip_path="./daily.zip",
dest_dir="./unzipped",
password=None,
overwrite=True
)

代码讲解

  • zipfile.ZipFile(zpath, 'r'):以只读模式打开zip,内部会自动识别压缩格式。
  • zf.namelist():列出压缩包里所有文件和目录的相对路径,返回字符串列表。
  • zf.extract(member, dest, pwd=pwd):把单个成员解压到目标目录,pwd参数接收bytes类型密码。
  • zip slip校验:计算目标文件的绝对路径后,判断它是否仍在dest目录内。恶意zip里可能包含../../etc/passwd这种路径,不加校验会把文件写到系统目录。
  • overwrite开关:设为False时遇到已存在文件就跳过,适合增量解压。

运行结果

脚本运行后,unzipped/目录下会还原出zip包内的完整目录结构,命令行打印解压的条目数量。打开解压目录核对文件是否齐全即可。

注意事项

  • 加密zip在Python 3里只支持传统ZipCrypto加密方式。如果压缩包是AES加密(7-Zip创建的),标准库解不开,需要用pyzipper第三方库。
  • 密码编码问题:Windows下用中文密码,部分压缩软件生成的包密码不是UTF-8编码,可能需要尝试gbk编码。
  • extractall()一行就能解压全部,但不支持逐文件覆盖控制和安全校验,生产环境建议按本示例逐文件处理。

Python解压zip压缩包教程:一行代码完整提取

标签:

更新时间:2026-09-14 21:19:43

上一篇:Python按文件大小批量筛选移动教程

下一篇:Python批量从文件名提取日期建子目录归档教程