如何递归提取zip文件?

新手上路,请多包涵

我有一个 zip 文件,其中包含三个 zip 文件,如下所示:

 zipfile.zip\
    dirA.zip\
         a
    dirB.zip\
         b
    dirC.zip\
         c

我想提取具有这些名称(dirA、dirB、dirC)的目录中 zip 文件内的所有内部 zip 文件。

基本上,我想以以下模式结束:

 output\
    dirA\
         a
    dirB\
         b
    dirC\
         c

我尝试了以下方法:

 import os, re
from zipfile import ZipFile

os.makedirs(directory)  # where directory is "\output"
with ZipFile(self.archive_name, "r") as archive:
    for id, files in data.items():
        if files:
            print("Creating", id)
            dirpath = os.path.join(directory, id)

            os.mkdir(dirpath)

            for file in files:
                match = pattern.match(filename)
                new = match.group(2)
                new_filename = os.path.join(dirpath, new)

                content = archive.open(file).read()
            with open(new_filename, "wb") as outfile:
                outfile.write(content)

但它只提取 zip 文件,我最终得到:

 output\
    dirA\
         dirA.zip
    dirB\
         dirB.zip
    dirC\
         dirC.zip

包括代码段在内的任何建议 都将不胜感激,因为我尝试了很多不同的东西,但没有成功阅读文档。

原文由 Yannis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 928
2 个回答

解压缩 zip 文件时,您可能希望将内部 zip 文件写入内存而不是将它们写入磁盘。为此,我使用 BytesIO

看看这段代码:

 import os
import io
import zipfile

def extract(filename):
    z = zipfile.ZipFile(filename)
    for f in z.namelist():
        # get directory name from file
        dirname = os.path.splitext(f)[0]
        # create new directory
        os.mkdir(dirname)
        # read inner zip file into bytes buffer
        content = io.BytesIO(z.read(f))
        zip_file = zipfile.ZipFile(content)
        for i in zip_file.namelist():
            zip_file.extract(i, dirname)

如果你运行 extract("zipfile.zip")zipfile.zip 作为:

 zipfile.zip/
    dirA.zip/
        a
    dirB.zip/
        b
    dirC.zip/
        c

输出应该是:

 dirA/
  a
dirB/
  b
dirC/
  c

原文由 Forge 发布,翻译遵循 CC BY-SA 3.0 许可协议

对于提取嵌套 zip 文件(任何嵌套级别)并清理原始 zip 文件的函数:

 import zipfile, re, os

def extract_nested_zip(zippedFile, toFolder):
    """ Extract a zip file including any nested zip files
        Delete the zip file(s) after extraction
    """
    with zipfile.ZipFile(zippedFile, 'r') as zfile:
        zfile.extractall(path=toFolder)
    os.remove(zippedFile)
    for root, dirs, files in os.walk(toFolder):
        for filename in files:
            if re.search(r'\.zip$', filename):
                fileSpec = os.path.join(root, filename)
                extract_nested_zip(fileSpec, root)

原文由 ronnydw 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题