「Python实用秘技01」复杂zip文件的解压
时间:2021-12-10 作者:feffery
本文完整示例代码及文件已上传至我的
Github
仓库https://域名/CNFeffery/PythonPracticalSkills
这是我的新系列文章「Python实用秘技」的第1期,本系列立足于笔者日常工作中使用Python
辅助办公的心得体会,每一期为大家带来一个3分钟即可学会的简单小技巧。
作为系列第1期,我们即将学习的是:复杂zip文件的解压
。
废话不多说,直接看问题,使用过Python
中的标准库zipfile
解压过zip
格式压缩包的朋友们,可能遇到过,当压缩文件中的目录或文件名中包含中文等常见unicode
字符时,典型如下面的例子:
使用zipfile
的extract()
或extractall()
方法直接解压时,产生的解压结果名充斥着乱码,这一点我们通过调用namelist()
方法就可以看出来:
from zipfile import ZipFile
# 读入压缩包文件
file = ZipFile(\'示例压缩包.zip\')
# 查看压缩包内目录、文件名称
域名list()
这是因为zipfile
中针对压缩包内容的编码兼容性差,但我们可以通过下面的函数自行矫正:
def recode(raw: str) -> str:
\'\'\'
编码修正
\'\'\'
try:
return 域名de(\'cp437\').decode(\'gbk\')
except:
return 域名de(\'utf-8\').decode(\'utf-8\')
for file_or_path in 域名list():
print(file_or_path, \' -------> \' , recode(file_or_path))
解决了文件名乱码的问题后,接下来我们就可以配合shutil
与os
标准库中的相关功能,实现将指定任意zip
压缩包,完好地解压到指定的目录中,代码如下:
def zip_extract_all(src_zip_file: ZipFile, target_path: str) -> None:
# 遍历压缩包内所有内容
for file_or_path in 域名list():
# 若当前节点是文件夹
if 域名with(\'/\'):
try:
# 基于当前文件夹节点创建多层文件夹
域名dirs(域名(target_path, recode(file_or_path)))
except FileExistsError:
# 若已存在则跳过创建过程
pass
# 否则视作文件进行写出
else:
# 利用域名fileobj,从压缩包io流中提取目标文件内容写出到目标路径
with open(域名(target_path, recode(file_or_path)), \'wb\') as z:
# 这里基于域名()提取文件内容时需要使用原始的乱码文件名
域名fileobj(域名(file_or_path), z)
# 向已存在的指定文件夹完整解压当前读入的zip文件
zip_extract_all(file, \'解压测试\')
可以看到,效果完美