2016-03-29 23 views
7

Tôi có một file zip có chứa ba file zip trong nó như thế này:Làm thế nào để giải nén file zip đệ quy bằng Python

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

tôi muốn trích xuất tất cả các file zip bên trong mà bên trong file zip trong thư mục với những cái tên này (dirA, dirB, dirC).
Về cơ bản, tôi muốn kết thúc với các lược đồ sau:

output\ 
    dirA\ 
     a 
    dirB\ 
     b 
    dirC\ 
     c 

Tôi đã thử những điều sau đây:

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) 

Nhưng nó chỉ trích xuất các tập tin zip và tôi kết thúc với:

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

Mọi đề xuất bao gồm các đoạn mã sẽ được nhiều người đánh giá cao vì tôi đã thử rất nhiều hings và đọc các tài liệu mà không thành công.

+0

Vui lòng sửa đổi câu hỏi của bạn và cung cấp [_Minimal, Complete, and Verifiable example_] (https://stackoverflow.com/help/mcve) bao gồm những gì trong 'data.items()'. – martineau

+0

@martineau Cảm ơn bạn đã bình luận. Như đã trình bày ở trên, dữ liệu giữ \ zipfile.zip> dirA.zip> một \ zipfile.zip> dirB.zip> b \ zipfile.zip> dirC.zip> c tôi đã cố gắng để làm cho câu hỏi một chút tổng quát hơn và không phụ thuộc vào bất kỳ 'dữ liệu' nào nắm giữ, ngoại trừ thực tế là có các phần nén bên trong của một mã zip. – Yannis

Trả lời

4

Khi giải nén tệp nén, bạn sẽ muốn ghi các tệp zip bên trong vào bộ nhớ thay vì chúng trên đĩa. Để làm điều này, tôi đã sử dụng BytesIO.

Kiểm tra mã này:

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) 

Nếu bạn chạy extract("zipfile.zip") với zipfile.zip như:

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

Output nên là:

dirA/ 
    a 
dirB/ 
    b 
dirC/ 
    c 
+0

@Yannis kiểm tra câu trả lời cập nhật. – Forge

+0

Chính xác những gì tôi đang tìm kiếm, nó trích xuất như được mô tả trong câu hỏi của tôi. Cảm ơn! – Yannis

+0

@Forge Lỗi: sub_zip không được xác định –

0

Đối với một chức năng mà trích ra một zip lồng nhau tệp (mọi cấp độ lồng nhau) và dọn dẹp các tệp zip gốc:

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) 
Các vấn đề liên quan