常见原因是文件下载不完整或服务器返回HTML错误页;应先用file命令或检查前4字节b'PK\x03\x04'验证ZIP格式,再检查HTTP状态码确保为200。

下载完 zip 文件后 zipfile.is_zipfile() 返回 False 怎么办
常见原因是文件没下载完整,或者服务器返回了 HTML 错误页(比如 404、重定向页面)却被当成了 zip 写入磁盘。别急着改解压逻辑,先验证文件本身是否真为 ZIP。
- 用
file命令检查(Linux/macOS):file downloaded.zip—— 正常 ZIP 应含Zip archive data - Python 中加一层校验:下载后立即用
open('downloaded.zip', 'rb').read(4)看前 4 字节是不是b'PK\x03\x04' - requests 下载时务必显式检查状态码:
if resp.status_code != 200,并避免用stream=False默认行为直接写文件
用 zipfile.ZipFile 解压中文路径报 UnicodeDecodeError
Python 3.6+ 的 zipfile 默认用 CP437 解码文件名,而国内 Windows 打包的 ZIP 多用 GBK/UTF-8。这不是编码“错”,是 ZIP 标准本身没强制规定编码,解压器得猜。
- 简单兼容方案:用
zipfile.ZipFile的pwd参数无效,但可手动修复成员名:for info in zf.filelist: info.filename = info.filename.encode('cp437').decode('gbk', 'ignore') - 更稳做法:改用
py7zr或patoolib,它们对中文路径支持更鲁棒,尤其处理老版 WinRAR 打的包 - 如果必须用原生
zipfile,且确认源 ZIP 是 UTF-8 编码(如 Pythonzipfile.write()生成的),可设zf = zipfile.ZipFile(..., metadata_encoding='utf-8')(仅 3.11+)
shutil.unpack_archive() 和手写 zipfile 循环解压,选哪个
shutil.unpack_archive() 看似省事,但底层调的还是 zipfile / tarfile,只是封装了一层;它不支持进度反馈、单文件过滤、密码解压,出错时堆栈也更模糊。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 日常脚本、无需干预:用
shutil.unpack_archive(path, extract_dir)没问题,代码少、可读性高 - 需要跳过某些文件(比如
.DS_Store)、校验 CRC、记录解压耗时、或捕获单个文件解压失败继续执行 —— 必须手写zipfile.ZipFile+extract()或extractall() - 注意
shutil.unpack_archive()对路径处理较粗暴,遇到../会直接创建在父目录,有安全风险;手写时可用os.path.relpath(info.filename)做白名单校验
解压大 ZIP 时内存暴涨或卡死,extractall() 还是逐个 extract()
extractall() 本质是循环调 extract(),但默认把整个 ZIP 的元数据一次性加载进内存(filelist),对超大 ZIP(上万文件)可能吃掉几百 MB。真正影响性能的是磁盘 I/O 和路径解析,不是函数选型本身。
立即学习“Python免费学习笔记(深入)”;
- 内存敏感场景:用
for info in zf.infolist(): zf.extract(info, path),避免一次性 hold 所有ZipInfo对象 - 想限速或加进度条:只能逐个
extract(),配合tqdm或简单计数器 - 别忽略
zf.close()—— 尤其在try/finally里没写,大 ZIP 可能导致文件句柄泄漏,后续操作报OSError: [Errno 24] Too many open files

















