2016-03-29 26 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)