Библиотека zipfile Python - создайте zip-файл, содержащий только файлы .pdf и .xml из одного каталога - PullRequest
1 голос
/ 02 октября 2019

Я хотел бы знать, как я могу заархивировать только все PDF-файлы из основного каталога, не включая вложенные папки.

Я несколько раз пытался изменить код без каких-либо успехов с тем, чего я хочу достичь.

import zipfile

fantasy_zip = zipfile.ZipFile('/home/rob/Desktop/projects/zenjobv2/archivetest.zip', 'w')

for folder, subfolders, files in os.walk('/home/rob/Desktop/projects/zenjobv2/'):

    for file in files:
        if file.endswith('.pdf'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), '/home/rob/Desktop/projects/zenjobv2/'), compress_type = zipfile.ZIP_DEFLATED)
        elif file.endswith('.xml'):
            fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), '/home/rob/Desktop/projects/zenjobv2/'), compress_type = zipfile.ZIP_DEFLATED)
fantasy_zip.close()

Я ожидаю, что zip создается только с файлами .pdfs и .xml из папки / каталога zenjobv2 без включения других папок / подпапок.

(отредактировано) Решение:

import os, glob
import zipfile

fantasy_zip = zipfile.ZipFile('/home/rob/Desktop/projects/zenjobv2/archivetest.zip', 'w')

root = "/home/rob/Desktop/projects/zenjobv2"

for file in os.listdir(root):
    if file.endswith('.pdf') or file.endswith(".xml"):
        fantasy_zip.write(file)
fantasy_zip.close()

1 Ответ

1 голос
/ 02 октября 2019

Обновлено с новой информацией из OP:

Вы перебираете все дерево каталогов с os.walk(). Похоже, вы хотите просто посмотреть на файлы в данном каталоге. Для этого рассмотрим os.scandir(), который возвращает итератор всех файлов и подкаталогов в данном каталоге. Вам просто нужно отфильтровать элементы, которые являются каталогами:

root = "/home/rob/Desktop/projects/zenjobv2"
for entry in os.scandir(root):
    if entry.is_dir():
        continue  # Just in case there are strangely-named directories
    if entry.path.endswith(".pdf") or entry.path.endswith(".xml"):
        # Process the file at entry.path as you see fit

Предыдущий ответ, основанный на плохом понимании вопроса:

Вы неявно указываете аргумент arcname в вашем вызове ZipFile.write(), который создаст файл в архиве с точным указанным вами путем, подкаталогами и всем. Если файл, который вы добавляете в архив, находится по пути /home/rob/Desktop/projects/zenjobv2/subdir1/subdir2/file.pdf, то, используя определение os.path.relpath(), ваш код фактически преобразуется в:

fantasy_zip.write("/home/rob/Desktop/projects/zenjobv2/subdir1/subdir2/file.pdf",
                  arcname="subdir1/subdir2/file.pdf",
                  compress_type=zipfile.ZIP_DEFLATED)

, поскольку arcname аргумент содержит разделители каталогов, файл будет добавлен в архив в подкаталоге с именем subdir1/subdir2.

Вы, вероятно, намереваетесь сделать что-то вроде этого:

fantasy_zip.write(os.path.join(folder, file), arcname=file)

Этооставит структуру каталогов вне архива. Однако следует помнить, что файлы с одинаковыми именами будут перезаписаны.

...