26

I am looking to unzip a particular folder from a .zip in Python:

e.g. archive.zip contains the folders foo and bar, I want to unzip foo to a specific location, retaining it's folder structure.

James
  • 30,496
  • 19
  • 86
  • 113
  • http://stackoverflow.com/questions/639962/unzipping-directory-structure-with-python this question looks pretty similar – cleg Dec 07 '12 at 14:55
  • 2
    @cleg It's not, that question is just about retaining directory structure - which I know how to do. I want to know how to extract a particular folder from a zip. – James Dec 07 '12 at 14:57

4 Answers4

42

Check zipfile module.

For your case:

import zipfile

archive = zipfile.ZipFile('archive.zip')

for file in archive.namelist():
    if file.startswith('foo/'):
        archive.extract(file, 'destination_path')
phoenix
  • 7,988
  • 6
  • 39
  • 45
kaspersky
  • 3,959
  • 4
  • 33
  • 50
  • The first matching item returned by namelist() will be the folder 'foo/'. If that's likely to cause problems, you can just add something like if file.startswith('foo/') and file != 'foo/' – Violet May 13 '21 at 09:27
  • 9
    That works, but any way to extract the folder without its ancestors? E.g. if I want to extract `foo` from `archive.zip/foobar/bar/foo/`, the line `archive.extract(file, 'destination_path')` will extract to `destination_path/foobar/bar/foo/file`, while I would like it to extract to `destination_path/foo/file` – Alaa M. Aug 31 '21 at 12:00
  • Incase any one else is facing the issue mentioned by `Alaa M`, [this](https://stackoverflow.com/a/56362289/7073174) is a solution that worked for me – Abhijith Bagepalli Jan 17 '23 at 20:59
1

I like to reduce the list of names first so that the for loop doesn't parse through all the files in the zip archive:

import zipfile

archive = zipfile.ZipFile('archive.zip')

names_foo = [i for i in archive.namelist() if i.startswith('foo') ]

for file in names_foo:
    archive.extract(file)
1

You should close your zips....


import zipfile

archive = zipfile.ZipFile('archive.zip')

for file in archive.namelist():
    if file.startswith('foo/'):
        archive.extract(file, 'destination_path')

archive.close()

Or just use a safer method. With will close your zip.

import zipfile
with zipfile.ZipFile('archive.zip') as archive:
    for file in archive.namelist():
        if file.startswith('foo/'):
            archive.extract(file, 'destination_path')
-3

using zipfile library is very very slow. this is better way:

os.system('unzip -P your-password path/to/file.zip')
Sajjad Aemmi
  • 2,120
  • 3
  • 13
  • 25