Je voudrais écrire un script simple pour parcourir tous les fichiers d'un dossier et décompresser ceux qui sont zippés (.zip) dans ce même dossier. Pour ce projet, j'ai un dossier avec près de 100 fichiers .las zippés et j'espère un moyen facile de les décompresser par lots. J'ai essayé avec le script suivant

import os, zipfile

folder = 'D:/GISData/LiDAR/SomeFolder'
extension = ".zip"

for item in os.listdir(folder):
    if item.endswith(extension):
        zipfile.ZipFile.extract(item)

Cependant, lorsque j'exécute le script, j'obtiens l'erreur suivante:

Traceback (most recent call last):
  File "D:/GISData/Tools/MO_Tools/BatchUnzip.py", line 10, in <module>
    extract = zipfile.ZipFile.extract(item)
TypeError: unbound method extract() must be called with ZipFile instance as first argument (got str instance instead)

J'utilise l'interpréteur python 2.7.5. J'ai regardé la documentation du module zipfile (https: //docs.python .org / 2 / library / zipfile.html # module-zipfile) et je voudrais comprendre ce que je fais mal.

Je suppose que dans mon esprit, le processus se déroulerait comme ceci:

  1. Obtenir le nom du dossier
  2. Parcourez le dossier et recherchez les fichiers zip
  3. Extraire les fichiers zip dans un dossier

Merci Marcus, cependant, lors de la mise en œuvre de la suggestion, je reçois une autre erreur:

Traceback (most recent call last):
  File "D:/GISData/Tools/MO_Tools/BatchUnzip.py", line 12, in <module>
    zipfile.ZipFile(item).extract()
  File "C:\Python27\ArcGIS10.2\lib\zipfile.py", line 752, in __init__
    self.fp = open(file, modeDict[mode])
IOError: [Errno 2] No such file or directory: 'JeffCity_0752.las.zip'

Lorsque j'utilise des instructions d'impression, je peux voir que les fichiers s'y trouvent. Par exemple:

for item in os.listdir(folder):
    if item.endswith(extension):
        print os.path.abspath(item)
        filename = os.path.basename(item)
        print filename

Rendements:

D:\GISData\Tools\MO_Tools\JeffCity_0752.las.zip
JeffCity_0752.las.zip
D:\GISData\Tools\MO_Tools\JeffCity_0753.las.zip
JeffCity_0753.las.zip

Si je comprends bien la documentation,

zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

Ouvrez un fichier ZIP, où le fichier peut être un chemin d'accès à un fichier (une chaîne) ou un objet de type fichier

Il me semble que tout est présent et expliqué. Je ne comprends tout simplement pas ce que je fais mal.

Aucune suggestion?

Merci

31
tpdance 10 juil. 2015 à 20:23

4 réponses

Meilleure réponse

Voici le code qui a fonctionné pour moi:

import os, zipfile

dir_name = 'C:\\SomeDirectory'
extension = ".zip"

os.chdir(dir_name) # change directory from working dir to dir with files

for item in os.listdir(dir_name): # loop through items in dir
    if item.endswith(extension): # check for ".zip" extension
        file_name = os.path.abspath(item) # get full path of files
        zip_ref = zipfile.ZipFile(file_name) # create zipfile object
        zip_ref.extractall(dir_name) # extract file to dir
        zip_ref.close() # close file
        os.remove(file_name) # delete zipped file

En repensant au code que j'avais modifié, le répertoire se confondait avec le répertoire du script.

Ce qui suit fonctionne également sans ruiner le répertoire de travail. Retirez d'abord la ligne

os.chdir(dir_name) # change directory from working dir to dir with files

Attribuez ensuite nom_fichier à

file_name = dir_name + "/" + item
29
Chenlu 7 févr. 2017 à 22:22

La réponse acceptée fonctionne très bien!

Juste pour étendre l'idée de décompresser tous les fichiers avec l'extension .zip dans tous les sous-répertoires d'un répertoire, le code suivant semble bien fonctionner:

import os
import zipfile

for path, dir_list, file_list in os.walk(dir_path):
    for file_name in file_list:
        if file_name.endswith(".zip"):
            abs_file_path = os.path.join(path, file_name)

            # The following three lines of code are only useful if 
            # a. the zip file is to unzipped in it's parent folder and 
            # b. inside the folder of the same name as the file

            parent_path = os.path.split(abs_file_path)[0]
            output_folder_name = os.path.splitext(abs_file_path)[0]
            output_path = os.path.join(parent_path, output_folder_name)

            zip_obj = zipfile.ZipFile(abs_file_path, 'r')
            zip_obj.extractall(output_path)
            zip_obj.close()
5
user11015000 5 févr. 2019 à 07:35

Je pense que c'est plus court et a bien fonctionné pour moi. Importez d'abord les modules requis:

import zipfile, os

Ensuite, je définis le répertoire de travail:

working_directory = 'my_directory'
os.chdir(working_directory)

Après cela, vous pouvez utiliser une combinaison des os et zipfile pour arriver où vous voulez:

for file in os.listdir(working_directory):   # get the list of files
    if zipfile.is_zipfile(file): # if it is a zipfile, extract it
        with zipfile.ZipFile(file) as item: # treat the file as a zip
           item.extractall()  # extract it in the working directory
3
Bondify 2 juil. 2019 à 10:14

Vous devez construire un objet ZipFile avec le nom de fichier et puis l'extraire:

    zipfile.ZipFile.extract(item)

Est faux.

    zipfile.ZipFile(item).extractall()

Extraira tous les fichiers du fichier zip avec le nom contenu dans item.

Je pense que vous devriez lire la documentation de plus près à zipfile :) mais vous êtes sur la bonne voie!

4
Marcus Müller 10 juil. 2015 à 17:27