解决Python zip文件的解压问题

废话不多说,直接看问题,使用过 Python 中的标准库 zipfile 解压过 zip 格式压缩包的朋友们,可能遇到过,当压缩文件中的目录或文件名中包含中文等常见 unicode 字符时,典型如下面的例子:

使用 zipfile 的 extract() 或 extractall() 方法直接解压时,产生的解压结果名充斥着乱码,这一点我们通过调用 namelist() 方法就可以看出来:

from zipfile import ZipFile

# 读入压缩包文件
file = ZipFile('示例压缩包.zip')

# 查看压缩包内目录、文件名称
file.namelist()

这是因为 zipfile 中针对压缩包内容的编码兼容性差,但我们可以通过下面的函数自行矫正:

def recode(raw: str) -> str:
  '''
  编码修正
  '''
  
  try:
      return raw.encode('cp437').decode('gbk')
  
  except:
      return raw.encode('utf-8').decode('utf-8')
  
for file_or_path in file.namelist():
  
  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 file.namelist():
      
      # 若当前节点是文件夹
      if file_or_path.endswith('/'):
          try:
              # 基于当前文件夹节点创建多层文件夹
              os.makedirs(os.path.join(target_path, recode(file_or_path)))
          except FileExistsError:
              # 若已存在则跳过创建过程
              pass
      
      # 否则视作文件进行写出
      else:
          # 利用shutil.copyfileobj,从压缩包io流中提取目标文件内容写出到目标路径
          with open(os.path.join(target_path, recode(file_or_path)), 'wb') as z:
              # 这里基于Zipfile.open()提取文件内容时需要使用原始的乱码文件名
              shutil.copyfileobj(src_zip_file.open(file_or_path), z)
          
# 向已存在的指定文件夹完整解压当前读入的zip文件
zip_extract_all(file, '解压测试')

可以看到,效果完美 :

关于Python复杂zip文件的解压的文章就介绍至此,更多相关Python zip文件的解压内容请搜索编程宝库以前的文章,希望以后支持编程宝库

Python里,简单的人脸识别有很多种方法可以实现,依赖于python胶水语言的特性,我们通过调用包可以快速准确的达成这一目的。这里介绍的是准确性比较高的一种。 一、首先梳理一下实现人脸识别需要进行 ...