Lerne Coding
ZIP-Dateien erstellen und lesen mit Python
31.12.2020

Python mit ZIP-Dateien arbeiten

Inhaltsverzeichnis
[[TABLE OF CONTENTS]]
access_timeGeschätzte Lesezeit ca. Minuten

Eine ZIP-Datei ist ein Container- und Archive-Format, das eine verlustfreie Komprimierung von Dateien ermöglicht. Deshalb wird es gerne für Backups verwendet oder für das Versenden mehrerer Dateien per E-Mail; hier dann als Container für die Daten.

So lässt sich das ZIP-Format auch für größere Archive verwenden, die selten geöffnet werden - wo somit Speicher gespart werden kann.

Dieses Container- bzw. Archive-Format können wir auch in Python verwenden. In dieser Anleitung will ich dir einen Überblick geben, wie du mit dem ZIP-Format in Python arbeiten kannst. Also wie du ZIP-Dateien einlesen und wie du einen Ordner zippen kannst.

Falls du dich mehr für PHP interessierst, habe ich noch einen ähnlichen Artikel zu dem Thema für PHP verfasst. Diesen findest du hier: "Arbeiten in PHP mit ZIP-Archiven".

Einen Ordner als ZIP-Datei verpacken in Python

Einen Ordner als ZIP-Datei zu verpacken ist mit dem Paket zipfile möglich. In Python es gibt leider keine Standard-Methode, um einfach den Ordner zu zippen, sondern es ist notwendig, jede Datei einzeln abzulegen. Um das zu realisieren, verwenden wir zusätzlich das Modul OS um alle Dateien aus dem Python-Verzeichnis und darunter liegenden Ordnern in die ZIP-Datei zu inkludieren.

Als Beispiel habe ich eine kleine Funktion geschrieben. Diese erwartet 2 Parameter, kann aber auch einen optionalen dritten entgehen nehmen.

  • folder - der Ordner, der als ZIP abgelegt werden soll
  • filename - der Dateiname der neuen ZIP-Datei
  • compress - die Art der Komprimierung; standardmäßig haben wir hier Deflated eingestellt.

Innerhalb der Funktion öffnen wir als Erstes eine neue ZIP-Datei mit Context Manager erstellen. Das heißt, wir verwenden das with-Keyword. Die Verwendung mit Context Manager funktioniert ab Python 3.2. Mit der Methode write können neue Dateien in das ZIP-Archive eingefügt werden. Mittels der Methode os.walk können wir über ein Verzeichnis iterieren und alle Dateien erhalten. Mehr dazu im Artikel "In Python Verzeichnisse einlesen".

Zusätzlich lassen wir uns im Terminal noch anzeigen, welche Dateien in das ZIP-Archive eingefügt worden sind.

import os,zipfile

def createZIP(folder,filename,compress = zipfile.ZIP_DEFLATED):
        # ZIP Archive Öffnen
    with zipfile.ZipFile(filename + '.zip', 'w', compress) as target:
        for root, dirs, files in os.walk(folder):
            for file in files:
                add = os.path.join(root, file)

                                # Datei zum ZIP Archive Hinzufügen
                target.write(add)

                print(add + ' wurde Hinzugefügt')

# ZIP Archive vom Verzeichnis "bilder" erstellen.
createZIP('bilder','bilder-archive')

Und so einfach können wir nun vom Verzeichnis "bilder" ein ZIP-Archive erstellen und danach zum Beispiel als E-Mail versenden.

Eine ZIP-Datei in einen Ordner entpacken

Das Extrahieren von ZIP-Files funktioniert sehr einfach. Als erstes öffnen wir die Datei wieder mit Context Manager (ab Python 3.2). Danach können wir die Methode extractall verwenden und ein Verzeichnis angeben, in dem das ZIP-Archive entpackt werden soll. Beim Öffnen solltest du den Modus r fürs Lesen nehmen.

import zipfile

with zipfile.ZipFile('example.zip','r') as source:
    source.extractall('bilder-archive')

So kannst du nun schnell und einfach eine ZIP-Datei in einen Ordner entpacken. Alternativ, falls du eine ältere Version von Python verwendest, geht es auch ganz einfach ohne Context Manager; und zwar wie folgt:

import zipfile

source = zipfile.ZipFile('example.zip','r') 

source.extractall('bilder-archive')

source.close()

Der Vorteil am Context Manager ist, dass du die ZIP-Datei nicht mehr abschließend schließen brauchst, da der Manager das selbständig beim Verlassen der Einrückung macht.

Dateien aus einer ZIP-Datei lesen, ohne zu extrahieren

Manchmal kommt es vor, dass du zum Beispiel Dateien aus einer ZIP-Datei verwenden willst, zum Beispiel für ein Import-Tool. Aber du willst diese nicht vorher extrahieren, weil du den Ordner am Ende nur wieder Löschen würdest? Das kannst du auch tun mit der read-Methode. Oder wenn du ein File-Objekt haben willst, kannst du auch die Methode open mit Pfadangabe verwenden.

Und vorher willst du noch wissen, welche Dateien in deinem ZIP-Archive überhaupt vorhanden sind? Das kannst du mit der Methode namelist herausfinden.

In unserem Beispiel verwenden wir noch die Methode decode, um die binären Daten in eine String umzuwandeln.

import zipfile

with zipfile.ZipFile('bilder-archive.zip','r') as source:
    # Erhalte eine Liste mit alle Dateien die in dem ZIP Vorhanden sind
    print(source.namelist())

    # Ein Bestimmte Datei aus dem ZIP Lesen und in einen String Convertieren
    print(source.read('bilder/test.txt').decode('utf-8'))

ZIP-Dateien mit Passwort extrahieren

Das Extrahieren von Dateien mit Passwörtern funktioniert genauso einfach wie ohne: Es wird bei der Methode extractall ein zweiter Parameter pwd übergeben. Dieser erwartet bytes, weshalb wir unseren String in bytes konvertieren müssen. Danach ist das ZIP-Archive mit Passwortschutz entpackt.

import zipfile

with zipfile.ZipFile('pwd-zip.zip','r') as source:
    source.extractall('test-test', pwd = bytes('123','utf-8'))

ZIP-Archive mit Passwortschutz erstellen

Ein ZIP-Archive mit Passwortschutz in Python zu erstellen ist leider nicht so einfach, da das Modul zipfile keine Option unterstützt, um eine passwortgeschütze ZIP zu erstellen. Unter Linux und macOS gibt es allerdings einen Standardbefehl, den man verwenden kann.

zip -P Passwort -r dateiname.zip verzeichnis

Da wir diesen Befehl haben, können wir ihn natürlich auch mit Python ansteuern. Ich habe auch nach anderen Möglichkeiten mit fertigen Paketen gesucht. Allerdings ist die Lösung, auf die immer wieder aufmerksam gemacht wird, die Nutzung dieses Befehls.

Unter Windows könnte man sich zum Beispiel 7zip installieren. Dieses Programm hat auch entsprechende Commands für die CLI.

Um Befehle vom System ausführen zu können, müssen wir das Modul subprocess verwenden. Darüber können wir Commands mit Argumenten erstellen. Da wir nun eine Funktion schreiben, die nur auf Linux und macOS funktioniert, fragen wir mit dem Modul platform vorher ab, ob es ein Linux-Betriebssystem oder macOS bzw. Darwin ist. Das ist eine andere Bezeichnung für macOS.

Für Windows haben wir das Programm 7zip entsprechend installiert. Für die Command Line sind wir betriebssystemunabhängig und können das auf allen Betriebssystemen verwenden. Ein Nachteil daran ist, dass 7zip vorher korrekt installiert werden muss.

Danach haben wir eine Abfrage, ob das Passwort gesetzt wurde. Falls nicht, wird der Command ohne den Passwortparameter ausgeführt.

Abschließend prüfen wir, ob unsere ZIP-Datei erstellt wurde, damit wir sichergehen können, dass alles korrekt gelaufen ist.

import platform,subprocess,os

def zip(name,path,pwd = ""):
    file = name + '.zip'

    if platform.system() in ["Linux","Darwin"]:
        if pwd != "":
            subprocess.run(["zip", "-P", pwd, '-r', file, path])
        else:
            subprocess.run(["zip",'-r', file, path])

    if platform.system() == "Windows":
        if pwd != "":
            subprocess.run(['7za',"a",file,path + "/*",'-p' + pwd])
        else:
            subprocess.run(['7za',"a",file,path + "/*"])

    return file in os.listdir('.')

Der Aufruf der Funktion um eine ZIP mit Passwortschutz zu erstellen, könnte zum Beispiel so aussehen:

if zip('test','bilder','123'):
    print("ZIP wurde Erstellt.")
else:
        print("ZIP wurde nicht Erstellt.")

Du siehst: auch wenn Python keine native Funktion liefert, um ein ZIP-Archive mit Passwort zu erstellen, kannst du dafür auf Shell Commands zugreifen und so dir die Option selbst integrieren.

Fazit

In diesem Artikel hast du gelesen, dass das Arbeiten mit ZIP-Dateien keinesfalls schwer ist und du es auf jeden Fall beherrschen solltest, wenn du große Datenpakete aus deiner Anwendung exportieren oder importieren willst. Das Arbeiten mit ZIP-Archiven in Python geht mit dem Paket zipfile definitiv sehr einfach und benötigt nicht viel Aufwand.

Bildquelle - Vielen Dank an die Ersteller:innen für dieses Bild
Kommentare zum Artikel
Guido Niendorf schreibt ... Kommentar vom 25.04.2024
Danke

Hallo Felix, Danke für diesen Beitrag. Deine Funktion createZIP hat mir gerade Arbeit erspart. Sehr gut aufbereitet, schön dargestellt - ich werde meinen Schüler_innen Deine Seite weiter empfehlen.

Viele Grüße Guido

Antworten
Guido Niendorf
Kommentar schreiben

Vom Autor Empfohlen
close