2016-03-29 212 views
7

我有一个包含有三个zip文件这样一个zip文件:如何递归地解压缩zip文件在Python

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

我想提取所有的都在目录中的zip文件中的内部zip文件与这些名字(dirA,dirB,dirC)。
基本上,我想下面的模式来结束:

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 

任何建议包括代码段将不胜感激因为我已经尝试了这么多不同的t打听并阅读文档没有成功。

+0

请修改您的问题并提供[_Minimal,Complete,and Verifiable example_](https://stackoverflow.com/help/mcve),其中包含data.items()中的内容。 – martineau

+0

@martineau感谢您的评论。 如上所述,数据保持 \ zipfile.zip> dirA.zip>一个 \ zipfile.zip> dirB.zip> b \ zipfile.zip> dirC.zip>Ç 我试图使问题的位更通用,不依赖于任何'数据',除了拉链内部有拉链。 – Yannis

回答

4

提取压缩文件时,您希望将内部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) 

如果用zipfile.zip为运行extract("zipfile.zip")

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

输出应该是:

dirA/ 
    a 
dirB/ 
    b 
dirC/ 
    c 
+0

@Yannis检查更新的答案。 – Forge

+0

正是我在找的东西,它按照我的问题进行提取。谢谢! – Yannis

+0

@Forge错误:未定义sub_zip –

0

对于提取嵌套压缩的功能文件(任何级别的嵌套)并清理原始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)