Extract files from zip without keeping the structure using python ZipFile?

后端 未结 5 1620
栀梦
栀梦 2020-11-27 16:10

I try to extract all files from .zip containing subfolders in one folder. I want all the files from subfolders extract in only one folder without keeping the original struc

相关标签:
5条回答
  • 2020-11-27 16:24

    It is possible to iterate over the ZipFile.infolist(). On the returned ZipInfo objects you can then manipulate the filename to remove the directory part and finally extract it to a specified directory.

    import glob
    import zipfile
    import shutil
    import os
    
    my_dir = "D:\\Download\\"
    my_zip = "D:\\Download\\my_file.zip"
    
    with zipfile.ZipFile(my_zip) as zip:
        for zip_info in zip.infolist():
            if zip_info.filename[-1] == '/':
                continue
            zip_info.filename = os.path.basename(zip_info.filename)
            zip.extract(zip_info, my_dir)
    
    0 讨论(0)
  • 2020-11-27 16:26

    Just extract to bytes in memory,compute the filename, and write it there yourself, instead of letting the library do it - -mostly, just use the "read()" instead of "extract()" method:

    Python 3.6+ update(2020) - the same code from the original answer, but using pathlib.Path, which ease file-path manipulation and other operations (like "write_bytes")

    from pathlib import Path
    import zipfile
    import os
    
    my_dir = Path("D:\\Download\\")
    my_zip = my_dir / "my_file.zip"
    
    zip_file = zipfile.ZipFile(my_zip, 'r')
    for files in zip_file.namelist():
        data = zip_file.read(files, my_dir)
        myfile_path = my_dir / Path(files.filename).name
        myfile_path.write_bytes(data)
    zip_file.close()
    

    Original code in answer without pathlib:

    import zipfile
    import os
    
    my_dir = "D:\\Download\\"
    my_zip = "D:\\Download\\my_file.zip"
    
    zip_file = zipfile.ZipFile(my_zip, 'r')
    for files in zip_file.namelist():
        data = zip_file.read(files, my_dir)
        # I am almost shure zip represents directory separator
        # char as "/" regardless of OS, but I  don't have DOS or Windos here to test it
        myfile_path = os.path.join(my_dir, files.split("/")[-1])
        myfile = open(myfile_path, "wb")
        myfile.write(data)
        myfile.close()
    zip_file.close()
    
    0 讨论(0)
  • 2020-11-27 16:31

    A similar concept to the solution of Gerhard Götz, but adapted for extracting single files instead of the entire zip:

    with ZipFile(zipPath, 'r') as zipObj:
        zipInfo = zipObj.getinfo(path_in_zip))
        zipInfo.filename = os.path.basename(destination)
        zipObj.extract(zipInfo, os.path.dirname(os.path.realpath(destination)))
    
    0 讨论(0)
  • 2020-11-27 16:34

    In case you are getting badZipFile error. you can unzip the archive using 7zip sub process. assuming you have installed the 7zip then use the following code.

    import subprocess
    my_dir = destFolder #destination folder
    my_zip = destFolder + "/" + filename.zip #file you want to extract
    ziploc = "C:/Program Files/7-Zip/7z.exe" #location where 7zip is installed
    cmd = [ziploc, 'e',my_zip ,'-o'+ my_dir ,'*.txt' ,'-r' ] 
    #extracting only txt files and from all subdirectories
    sp = subprocess.Popen(cmd, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
    
    0 讨论(0)
  • 2020-11-27 16:41

    This opens file handles of members of the zip archive, extracts the filename and copies it to a target file (that's how ZipFile.extract works, without taken care of subdirectories).

    import os
    import shutil
    import zipfile
    
    my_dir = r"D:\Download"
    my_zip = r"D:\Download\my_file.zip"
    
    with zipfile.ZipFile(my_zip) as zip_file:
        for member in zip_file.namelist():
            filename = os.path.basename(member)
            # skip directories
            if not filename:
                continue
    
            # copy file (taken from zipfile's extract)
            source = zip_file.open(member)
            target = open(os.path.join(my_dir, filename), "wb")
            with source, target:
                shutil.copyfileobj(source, target)
    
    0 讨论(0)
提交回复
热议问题