Как распаковать архив python
Перейти к содержимому

Как распаковать архив python

  • автор:

Скачать и распаковать zip-архив

Подскажите, как с помощью библиотеки requests считать данные по имеющемуся url в папку — без .zip? Делаю:

r = requests.get('https:URL') with open('. ', 'wb') as code: code.write(r.content) 

Если я на месте . указываю файл, то он просто превращается папку с файлами(полученную из URL) непонятно во что. Работает только с Name.zip, но потом нужно разорхивировать, что очень неудобно.

Отслеживать
52.3k 11 11 золотых знаков 108 108 серебряных знаков 312 312 бронзовых знаков
задан 6 фев 2018 в 21:26
1 1 1 серебряный знак 3 3 бронзовых знака
Например можно было заголовок такой написать: Скачать и распаковать zip-архив , подобное уже делал
7 фев 2018 в 6:21

3 ответа 3

Сортировка: Сброс на вариант по умолчанию

import tempfile, os, zipfile import requests response = requests.get('https://URL') file = tempfile.TemporaryFile() file.write(response.content) fzip = zipfile.ZipFile(file) fzip.extractall('') file.close() fzip.close() 

Отслеживать
ответ дан 6 фев 2018 в 22:25
1,138 5 5 серебряных знаков 15 15 бронзовых знаков

Чтобы скачать и распаковать zip-архив в output папку в Питоне:

#!/usr/bin/env python import io import zipfile import requests # $ pip install requests r = requests.get("http://www.pythonchallenge.com/pc/def/channel.zip") with r, zipfile.ZipFile(io.BytesIO(r.content)) as archive: archive.extractall('output') 

Если вы сразу хотите информацию из распакованных файлов в вашем коде использовать, то можно налету распаковывать и читать файлы:

with r, zipfile.ZipFile(io.BytesIO(r.content)) as archive: print() 

Статья Работа с запароленными архивами с помощью Python

Распаковка zip-архивов с помощью Python и встроенной библиотеки zipfile довольно простое занятие. И, может быть я и не столкнулся с некоторыми трудностями, если бы не стал распаковывать с помощью этой библиотеки запароленный архив. Вот тут-то архиватор и не захотел с ним работать. Хотя, распаковка архивов с паролем в нем предусмотрена уже по умолчанию. Тогда я решил немного разобраться, почему же так происходит и как с этим быть. Таким образом, получилась небольшая заметка по поводу того, как распаковать запароленные архивы разными типами архиваторов с помощью Python.

000.jpg

Дисклеймер: данная статья служит для ознакомления и не призывает к действию.

На оригинальность вовсе не претендую. Я просто хочу поделиться с другими тем, на что было потрачено пару часов моего времени. Чтобы человек, который решил распаковать архив питоном, не столкнулся с теми же трудностями, что и я. Если, конечно же, он прочтет эту заметку.

Пара слов про архивы с паролем

Для начала нужно понять, что же такое архив с паролем. Это не что иное, как зашифрованный с помощью алгоритмов шифрования файл. А пароль, это ключ для дешифровки. Таким образом, архиватор, при упаковке и распаковке файлов в архив с паролем, шифрует или дешифрует их встроенными средствами.

Библиотека zipfile для шифрования и расшифровки файлов использует алгоритм ZIP-шифрования. Однако, файлы с паролем, созданные с помощью стандартного архиватора Linux используют уже другой алгоритм шифрования AES. И соответственно, распаковать архив созданный таким способом с помощью библиотеки zipfile не получается. Это же касается и формата архивов 7zip.

Про формат RAR вообще отдельный разговор. Так как он является проприетарным, а значит закрытым форматом, то инструменты для распаковки доступны для данного формата только те, что поставляются разработчиками данного архиватора. И хоть они и предоставляются бесплатно, все равно, без помощи данных инструментов распаковка зашифрованных архивов будет недоступной. Да и вообще распаковка, как таковая. Для python, в данный момент, доступны лишь оболочки, которые являются лишь интерфейсами для инструментов rar.

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

Что потребуется?

Для распаковки зашифрованного zip-архива нужно установить библиотеку pyzipper. В терминале выполняем команду:

pip install pyzipper

После чего импортируем загруженную библиотеку в скрипт:

Ну и можно распаковывать архивы. Я не стал писать какие-то специальные скрипты для распаковки. Вместо этого будут просто обозначены функции, с помощью которых можно это сделать.

Расшифровка и распаковка zip-архива

Ну и раз мы начали с zip-архивов, то ниже приведен код для расшифровки и распаковки:

# pip install pyzipper import pyzipper def decrypt(file_path, word): with pyzipper.AESZipFile(file_path, 'r', compression=pyzipper.ZIP_LZMA, encryption=pyzipper.WZ_AES) \ as extracted_zip: try: extracted_zip.extractall(pwd=word) except RuntimeError as ex: print(ex) decrypt('test.txt.zip', b'123')

pyzipper является контекстным, потому открываем его с помощью with. Используем класс AESZipFile, в который передаем необходимые аргументы. Здесь file_path – путь к запароленному архиву. compression – метод сжатия. encryption – алгоритм шифрования, который будет использован для расшифровки. А далее в extracted_zip.extractall(pwd=word) вызывается функция extractall для распаковки всего содержимого архива. Здесь также можно указать путь для распаковки в параметре path, а в параметре pwd указывается пароль или ключ к зашифрованному архиву. Если путь для распаковки не указан, архив распаковывается в ту же папку, где он и располагается. Ключ должен быть в байтовом формате. Поэтому, нужно его перед тем, как передавать его в функцию, в него перевести. Либо как в примере, либо, использовав функцию encode().

Распаковка и расшифровка 7zip-архива

У данного типа архива при шифровании может использоваться алгоритм на выбор. А потому библиотека, которая распаковывает такие архивы, в теории, должна уметь автоматически подбирать нужный алгоритм для распаковки.

Для распаковки 7zip я использовал библиотеку py7zr, которая устанавливается в терминале с помощью команды:

pip install py7zr

Далее она импортируется в скрипт. Вот небольшой код для расшифровки и распаковки:

# pip install py7zr import py7zr try: with py7zr.SevenZipFile('test.txt.7z', mode='r', password='123') as z: z.extractall() except py7zr.exceptions.Bad7zFile as ex: if str(ex) == 'not a 7z file': print('Файл не является 7zip')

Параметры для распаковки, это путь к файлу архива, метод, который используется для открытия зашифрованного файла. Так как файл расшифровывается и распаковывается, то здесь нужно использовать read. И пароль к зашифрованному файлу. Я пробовал указать для распаковки с помощью данной библиотеки zip-архив. И если оригинальный архиватор 7zip справляется с этим на ура, то в данном случае возникает исключение, текст которого так и гласит, что файл не является 7zip.

Расшифровка и распаковка RAR

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

Ссылка скрыта от гостей

. В данном случае скачивается исполняемый файл unrar.exe, который нужно положить либо в папку с расшифровываемым архивом, либо в папку WinRAR, которую нужно создать в Program Files. Для того чтобы библиотека, то есть интерфейс к данному экзешнику, корректно находил к ней путь. Ну и так как exe используется в ОС Windows, то, как вы поняли, речь пока идет о ней. Или, если у вас уже установлен архиватор WinRAR, качать ничего не надо. Библиотека использует для распаковки Rar.exe находящийся в папке с программой. Его, при отсутствии архиватора и большом желании можно найти в интернете и положить в папку с архивом для распаковки. Данная конструкция тоже будет работать.

А теперь о том, что понадобиться. А понадобиться установить библиотеку patoolib с помощью команды в терминале:

pip install patoolib.

Используется в коде она очень просто. Для начала импортируется в скрипт, а затем указывается в качестве опций путь для распаковки. И на этом все. Библиотека сама ищет Rar или Unrar.exe по заданным в ней путям и использует их в работе.

# pip install patoolib import patoolib patoolib.extract_archive("test.rar")

Здесь пароль для распаковки в коде не указывается, а вводиться в терминале. А значит, в автоматическом режиме данную конструкцию использовать не получиться. Есть еще библиотеки, которые выполняют похожие функции. Но, все они, в той или иной степени, используют инструменты Rar.

Если вы решите распаковать данный вид архива с помощью python в Linux, то вам нужно будет установить библиотеку unrar. Ну и rar, в придачу, чтобы была возможность эти архивы создавать. Мало ли, вдруг для чего-то может, потребуется.

sudo apt-get install -y rar unrar

Вот такая вот небольшая заметка. Надеюсь, что она кому-то поможет при работе с запароленными архивами. Хотя это и не секретная информация, но искать ее в куче статей о работе с архивами с помощью zipfile довольно нудно ))

Ну и небольшой код, который пытается работать с запароленными zip-архивами. А началось все с того, что у меня в архиве лежала нужная информация, а вот пароль на него я подзабыл. Потому и попробовал написать код для работы с запароленными архивами с помощью стандартной библиотеки и столкнулся с трудностями по расшифровке. Ну и соответственно, начал искать информацию:

Код для работы с запароленными zip-архивами

# pip install pyzipper # pip install tqdm import pyzipper from tqdm import tqdm def decrypt(extracted_zip, word): try: extracted_zip.extractall(pwd=word) except RuntimeError: pass except pyzipper.zipfile.BadZipFile: pass else: print(f'\n[+] Пароль найден: ') exit(0) def open_pass_list(wordlist, file_path): len_zip = len(list(open(wordlist, 'rb'))) with open(wordlist, 'r', errors='ignore') as wordlist: with pyzipper.AESZipFile(file_path, 'r', compression=pyzipper.ZIP_LZMA, encryption=pyzipper.WZ_AES) as extracted_zip: for word in tqdm(wordlist, total=len_zip, unit=' word'): decrypt(extracted_zip, word.strip().encode()) def main(): wordlist = input('[+] Введите путь к словарю: ') file_path = input('[+] Введите путь к архиву: ') print(" ") open_pass_list(wordlist, file_path) if __name__ == "__main__": main()

Работа с архивом идет по словарю. А потому, его надо где-то скачать. Впрочем, в интернете словарей великое множество. Но я использовал rockyou.txt. Это, наверно, один из самых больших словарей с паролями, которые я видел. Попадались мне и на 10 миллионов. Но тут, больше 14-ти. К слову, пароль я так и не нашел. Пришлось вспоминать самостоятельно ))

Спасибо за внимание. Надеюсь, что данная информация будет вам полезна

Извлечение Файлов из архива tar.gz (Python)

Извлечение всего tar-файла, осуществляется с помощью функции extractall(). Данная функция извлечет файл в текущей рабочей директории. Также можно определить путь для разархивирования файлов в другом месте.

Извлечение полного содержимого tar-файла:

>>> import tarfile
>>> tar = tarfile.open(«archive.tar.gz», «r»)
>>> tar.extractall()
>>> tar.extractall(r»c:\temp»)

Когда необходимо извлечь определенные файлы, используйте функцию extract()

>>> import tarfile
>>> tar = tarfile.open(«archive.tar.gz», «r:gz»)
>>> tar.extract(«text.txt»)
>>> tar.extract(«text.txt», r»c:\temp»)

Как распаковать архив python

Zip представляет наиболее популярный формат архивации и сжатия файлов. И язык Python имеет встроенный модуль для работы с ними — zipfile . С помощью этого модуля можно создавать, считывать, записывать zip-файлы, получать их содержимое и добавлять в них файлы. Также поддерживается шифрование, но не поддерживается дешифрование.

Для представления zip-файла в этом модуле определен класс ZipFile . Он имеет следующий конструктор:

ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True, compresslevel=None, *, strict_timestamps=True, metadata_encoding=None)
  • file : путь к zip-файлу
  • mode : режим открытия файла. Может принимать следующие значения:
    • r : применяется для чтения существующего файла
    • w : применяется для записи нового файла
    • a : применяется для добавления в файл
    • ZIP_STORED : архивация без сжатия (значение по умолчанию)
    • ZIP_DEFLATED : стандартный тип сжатия при архивации в zip
    • ZIP_BZIP2 : сжатие с помощью способа BZIP2
    • ZIP_LZMA : сжатие с помощью способа LZMA

    Для работы с файлами этот класс предоставляет ряд методов:

    • close() : закрывает zip-файл
    • getinfo() : возвращает информацию об одном файле из архива в виде объекта ZipInfo
    • namelist() : возвращает список файлов архива
    • infolist() : возвращает информацию обо всех файлах из архива в виде списока объектов ZipInfo
    • open() : предоставляет доступ к одному из файлов в архиве
    • read() : считывает файл из архива в набор байтов
    • extract() : извлекает из архива один файл
    • extractall() : извлекает все элементы из архива
    • setpassword() : устанавливает пароль для zip-файла
    • printdir() : выводит на консоль содержимое архива

    Создание и закрытие файла

    Для создания архивного файла в конструктор ZipFile передается режим «w» или «a»:

    from zipfile import ZipFile myzip = ZipFile("metanit.zip", "w")

    После выполнения кода в текущей папке будет создаваться пустой архивный файл «metanit.zip».

    После окончания работы с архивом для его закрытия применяется метод close() :

    from zipfile import ZipFile myzip = ZipFile("metanit.zip", "w") myzip.close()

    Но так как ZipFile также представляет менеджер контекста, то он поддерживает выражение with , которое определяет контекст и автоматически закрывает файл по завершению контекста:

    from zipfile import ZipFile with ZipFile("metanit.zip", "w") as myzip: pass

    Запись файлов в архив

    Для записи файлов в архив применяется файл write() :

    write(filename, arcname=None, compress_type=None, compresslevel=None)

    Первый параметр представляет файл, который записиывается в архив. Второй параметр — arcname устанавливает произвольное имя для файла внутри архива (по умолчанию это само имя файла). Третий параметр — compress_type представляет тип сжатия, а параметр compresslevel — уровень сжатия.

    Например, запишем в архив «metanit.zip» файл «hello.txt» (который, как предполагается, находится в той же папке, где и текущий скрипт python):

    from zipfile import ZipFile with ZipFile("metanit.zip", "w") as myzip: myzip.write("hello.txt")

    Стоит учитывать, что при открытии файла в режиме «w» при всех последующих записях текущее содержимое будет затираться, то есть фактически архивный файл будет создаваться заново. Если нам необходимо добавить, то необходимо определять zip-файл в режиме «a»:

    from zipfile import ZipFile with ZipFile("metanit.zip", "a") as myzip: myzip.write("hello2.txt") myzip.write("forest.jpg")

    Стоит отметить, что по умолчанию сжатие не применяется. Но при необходимости можно применить какой-нибудь способ сжатия и уровень сжатия»

    from zipfile import ZipFile, ZIP_DEFLATED with ZipFile("metanit.zip", "w", compression=ZIP_DEFLATED, compresslevel=3) as myzip: myzip.write("hello.txt")

    Необходимо учитывать, что если мы попробуем добавить в архив файлы с уже имеющимися именами, то консоль выведет предупреждение. Чтобы избежать наличия файлов с дублирующимися именами можно через второй папаметр метода write явным образом определить для них уникальное имя внутри архива:

    from zipfile import ZipFile with ZipFile("metanit.zip", "a") as myzip: myzip.write("hello.txt", "hello1.txt") myzip.write("hello.txt", "hello2.txt") myzip.write("hello.txt", "hello3.txt")

    Получение информации о файлах в архиве

    Метод infolist() возвращает информацию о файлах в архиве с виде списка, где каждый отдельный файл представлен объектом ZipInfo:

    from zipfile import ZipFile with ZipFile("metanit.zip", "a") as myzip: print(myzip.infolist())

    Класс ZipInfo предоставляет ряд атрибутов для хранения информации о файле. Основные из них:

    • filename : название файла
    • date_time : дата и время последнего изменения файла в виде кортежа в формате (год, месяц, день, час, минута, секунда)
    • compress_type : тип сжатия
    • compress_size : размер после сжатия
    • file_size : оригинальный размер файла до сжатия

    Получим эти данные по каждому отдельному файлу в архиве:

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: for item in myzip.infolist(): print(f"File Name: Date: Size: ")

    Примерный консольный вывод:

    File Name: hello.txt Date: (2022, 11, 23, 20, 21, 34) Size: 18 File Name: forest.jpg Date: (2022, 11, 19, 20, 46, 52) Size: 103956 File Name: hello1.txt Date: (2022, 11, 23, 20, 21, 34) Size: 18 File Name: hello2.txt Date: (2022, 11, 23, 20, 21, 34) Size: 18 File Name: hello3.txt Date: (2022, 11, 23, 20, 21, 34) Size: 18

    С помощью метода is_dir() можно проверить, является ли элемент в архиве папкой:

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: for item in myzip.infolist(): if(item.is_dir()): print(f"Папка: ") else: print(f"Файл: ")

    Если надо получить только список имен входящих в архив файлов, то применяется метод namelist() :

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: for item in myzip.namelist(): print(item)

    Консольный вывод в моем случае:

    hello.txt forest.jpg hello1.txt hello2.txt hello3.txt

    С помощью метода getinfo() можно получить данные по одному из архивированных файлов, передав в метод его имя в архиве. Результат метода — объект ZipInfo:

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: try: hello_file = myzip.getinfo("hello.txt") print(hello_file.file_size) except KeyError: print("Указанный файл отсутствует")

    Если в архиве не окажется элемента с указанным именем, то метод сгенерирует ошибку KeyError.

    Извлечение файлов из архива

    Для извлечения всех файлов из архива применяется метод extractall() :

    extractall(path=None, members=None, pwd=None)

    Первый параметр метода устанавливает каталог для извлечения архива (по умолчанию извлечение идет в текущий каталог). Параметр members представляет список строк — список названий файлов, которые надо извлечт из архива. И третий параметр — pwd представляет пароль, в случае если архив закрыт паролем.

    Например, извлечем все файлы из архива:

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: myzip.extractall()

    Извлечение в определенную папку:

    myzip.extractall(path="metanit")

    Извлечение части файлов:

    # извлекаем файлы "hello.txt", "forest.jpg" в папку "metanit2" myzip.extractall(path="metanit2", members=["hello.txt", "forest.jpg"])

    Для извлечения одного файла применяется метод extract() , в который в качестве обязательного параметра передается имя извлекаемого файла:

    myzip.extract("hello.txt")

    Считывание файла

    Метод read() позволяет считать содержимое файла из архива в набор байтов:

    from zipfile import ZipFile with ZipFile("metanit.zip", "r") as myzip: content = myzip.read("hello5.txt") print(content)

    Открытие файла

    Метод open() позволяет открывать отдельные файлы из архива без непосредственного их извлечения:

    open(name, mode='r', pwd=None, *, force_zip64=False)

    В качестве первого обязательного параметра передается имя файла внутри архива. Второй параметр — mode устанавливает режим открытия. Параметр pwd задает пароль, если файл защищен паролем. И параметр force_zip64 при значении True позволяет открывать файлы больше 4 Гб.

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

    from zipfile import ZipFile with ZipFile("metanit.zip", "a") as myzip: # записываем в архив новый файл "hello5.txt" with myzip.open("hello5.txt", "w") as hello_file: encoded_str = bytes("Python. ", "UTF-8") hello_file.write(encoded_str)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *