Извлеките содержимое указанной папки c из zip-архива в Python3 - PullRequest
1 голос
/ 19 февраля 2020

У меня есть zip-архив, внутренняя структура которого выглядит следующим образом:

file.zip
  |
   --- foo/
  |
   --- bar/
        |
         --- file1.txt
        |
         --- dir/
              |
               --- file2.txt

, и я хотел бы извлечь содержимое bar в выходной каталог, используя python3, получив что-то похожее итак:

output-dir/
    |
     --- file1.txt
    |
     --- dir/
          |
           --- file2.txt

Однако, когда я запускаю код ниже, оба bar и его содержимое извлекаются в output-dir

import zipfile

archive = zipfile.ZipFile('path/to/file.zip')

for archive_item in archive.namelist():
    if archive_item.startswith('bar/'):
        archive.extract(archive_item, 'path/to/output-dir')

Как я могу решить эту проблему? Спасибо!

1 Ответ

3 голосов
/ 19 февраля 2020

Вместо использования ZipFile.extract, используйте ZipFile.open, open и shutil.copyfileobj, чтобы поместить файл точно в нужное место, используя манипуляции с путями для создания выходного пути вам нужно.

archive = zipfile.ZipFile('path/to/file.zip')
PREFIX = 'bar/'
out = pathlib.Path('path/to/output-dir')
for archive_item in archive.namelist():
    if archive_item.startswith(PREFIX):
        # strip out the leading prefix then join to `out`, note that you 
        # may want to add some securing against path traversal if the zip
        # file comes from an untrusted source
        destpath = out.joinpath(archive_item[len(PREFIX):])
        # make sure destination directory exists otherwise `open` will fail
        os.makedirs(destpath.parent, exist_ok=True)
        with archive.open(archive_item) as source,
             open(destpath, 'wb') as dest:
            shutil.copyfileobj(source, dest)

что-то в этом роде.

...