Extraire le zip avec Python (prend en charge les noms de fichiers japonais)

Nom de fichier au format zip

Il semble que le codage du nom de fichier de chaque fichier archivé dans le fichier zip puisse spécifier la présence ou l'absence de l'indicateur UTF-8 (dans la version actuelle), mais le codage autre que UTF-8 ne peut pas être spécifié. ..

Lorsqu'il est compressé dans les paramètres régionaux japonais Windows (selon l'outil), le nom du fichier est écrit en Shift_JIS (CP932). La plupart des Linux et Mac modernes sont UTF-8.

Lors de la décompression d'un fichier zip compressé sur un autre système d'exploitation, il peut être décompressé sans problème s'il a l'indicateur UTF-8, mais si Shift_JIS (CP932) est utilisé, le nom du fichier est brouillé. Cela peut arriver.

Plus précisément, Windows → Linux / Mac, etc. Dans ce cas, vous pouvez utiliser un archiveur tel que ʻunarou corriger le nom de fichier brouillé avecconvmv`.

En dehors de cela, la bibliothèque ZipFile de Python ne reconnaît pas non plus correctement les noms de fichiers.

Bibliothèque ZipFile Python3

La bibliothèque ZipFile convertit les octets en chaînes au format UTF-8 s'il existe un indicateur UTF-8, sinon en tant que CP437.

Par conséquent, si vous essayez de développer en utilisant ZipFile.extractall () etc., le nom du fichier japonais sera développé avec des caractères déformés.

La solution de contournement consiste à reconvertir ZipInfo.filename en une chaîne d'octets comme CP437, puis à nouveau en une chaîne avec le codage correct et à l'appeler ZipFile.extract (ZipInfo).

import zipfile

f = r'/file/to/path'

with zipfile.ZipFile(f) as z:
    for info in z.infolist():
        info.filename = info.filename.encode('cp437').decode('cp932')
        z.extract(info)

Dans ce qui précède, le codage d'origine est traité comme CP932, mais en réalité ce n'est pas toujours le cas, il est donc préférable d'utiliser un jugement de codage ou un traitement d'exception.

Mais non ...!

Il n'y a pas de problème si le processus d'extraction à l'aide de ZipFile est exécuté sur un Mac, mais si vous essayez d'extraire sous Windows, une erreur se produira en fonction du nom du fichier.

ZipInfo.filename a remplacé ʻos.sep par /. Autrement dit, sous Windows, ` (\ x5c) est remplacé par / (\ x2f).

CP437 est un encodage de caractères à 1 octet, et les caractères d'impression ASCII (\ x20- \ x7f) sont compatibles ASCII, donc ce processus de remplacement est effectué (même s'il fait à l'origine partie de caractères multi-octets). Je vais finir. En conséquence, une fois que vous revenez à la chaîne d'octets, un modèle tel que b '\ x90 \ x2f' apparaîtra.

Shift_JIS (CP932) n'utilise jamais le deuxième octet \ x2f, donc lorsque vous essayez de convertir à nouveau une telle chaîne d'octets en une chaîne comme CP932, une erreur de décodage se produit. Je vais.

Ce problème se produit lorsque le deuxième octet est le caractère «\ x5c».

alors. C'est un soi-disant «mauvais caractère». (Bien que la raison de l'échec soit différente de celle-ci)

Non. J'ai complètement oublié les mauvais personnages de Shift_JIS (CP932) ces 10 dernières années. De plus, il est livré avec une sphère changeante que shift_JIS (CP932) devient une chaîne d'octets invalide en la remplaçant par \ x2f.

Solution

Les informations de nom de fichier (décodées en CP437) avant le processus de remplacement sont stockées dans ZipInfo.orig_filename, qui peuvent être utilisées pour résoudre le problème.

import os
import zipfile

f = r'/file/to/path'

with zipfile.ZipFile(f) as z:
    for info in z.infolist():
        info.filename = info.orig_filename.encode('cp437').decode('cp932')
        if os.sep != "/" and os.sep in info.filename:
            info.filename = info.filename.replace(os.sep, "/")
        z.extract(info)

Recommended Posts

Extraire le zip avec Python (prend en charge les noms de fichiers japonais)
Extraire le fichier xz avec python
Zip, décompressez avec python
Gérer les fichiers zip avec des noms de fichiers japonais dans Python 3
Envoyer du courrier japonais avec Python3
Analyse morphologique japonaise avec Python
Système de support de présentation avec Python3
Télécharger le fichier csv avec python
Extraire le modèle du fichier EML enregistré depuis Thunderbird avec python3.7
Sélectionnez le fichier dans la boîte de dialogue avec python → Afficher le nom du fichier dans la boîte de message
Essayez de déchiffrer les caractères déformés dans le nom du fichier joint avec Python
Extraire récursivement des fichiers zip avec python
[Automation] Extraire les rendez-vous Outlook avec Python
[Python] Ecrire dans un fichier csv avec Python
[Automatisé avec python! ] Partie 1: fichier de configuration
Téléchargement de fichiers implémenté avec Python + Bottle
Sortie vers un fichier csv avec Python
[Débutant] Extraire des chaînes de caractères avec Python
Parlez du texte japonais avec OpenJTalk + python
[Automatisé avec python! ] Partie 2: Fonctionnement des fichiers
Énumération de fichiers japonais avec le système Python2 sous Windows (contre-mesure du problème 5C)
Contrôle exclusif avec fichier de verrouillage en Python
Lire le fichier CSV avec python (Télécharger et analyser le fichier CSV)
Générer des données de test japonais avec Python Faker
Vérifier l'existence du fichier avec python
[Python] Récupère le nom de la variable avec str
Créez rapidement un fichier Excel avec Python #python
Extraire les lignes qui correspondent aux conditions d'un fichier texte avec python
Téléchargez les données de cours des actions japonaises avec Python
Remarques sur la réalisation de l'OCR japonais avec Python
Lisons le fichier RINEX avec Python ①
Extraire du texte japonais d'un PDF avec PDFMiner
Comment afficher le japonais python avec lolipop
[Python] Rendons matplotlib compatible avec le japonais
Enregistrer avec Python → Enregistrer le fichier (périphérique sonore + wave)
Comment entrer le japonais avec les malédictions Python
zip en python
Python / numpy> Lire le fichier de données avec la ligne de nom d'élément> Utiliser genfromtxt ()
J'ai créé un fichier de configuration avec Python
[Automation] Lire le courrier (fichier msg) avec Python
nginxparser: essayez d'analyser le fichier de configuration nginx avec Python
Comment lire un fichier CSV avec Python 2/3
Extraire uniquement le nom du fichier à l'exclusion du répertoire dans le répertoire
Essayez-le avec JupyterLab en Python japonais Word Cloud.
Parler en japonais avec gTTS (lire un fichier texte)
[Automation] Extraire le tableau en PDF avec Python
[Python] Comment lire des fichiers Excel avec des pandas
Convertir un fichier svg en png / ico avec Python
Lire les données de la table dans un fichier PDF avec Python
Lire le nom / la plage de cellules Excel avec Python VBA
Développer des applications Windows avec Python 3 + Tkinter (fichier exe)
Créer une image avec des caractères avec python (japonais)
[Python] Résumé des opérations sur les fichiers S3 avec boto3
Créer un fichier au format Photoshop (.psd) avec python
Extraire les pièces jointes reçues par Thunderbird avec Python
Convertir le code de caractère du fichier avec Python3