Extract files from zip without keeping the structure using python ZipFile?
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 taking care of subdirectories).
import osimport shutilimport zipfilemy_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)
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 globimport zipfileimport shutilimport osmy_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)
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 Pathimport zipfileimport osmy_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 zipfileimport osmy_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()