"" "... GB18030 Je pensais que ce serait la solution, car il a lu les premiers fichiers et les a décodés très bien." "" - Veuillez expliquer ce que vous voulez dire. Pour moi, il y a DEUX critères pour un décodage réussi: d'abord que raw_bytes.decode ('some_encoding') n'a pas échoué, d'autre part que l'unicode résultant lorsqu'il est affiché a du sens dans une langue particulière. Chaque fichier dans l'univers passera le premier test lorsqu'il est décodé avec latin1
aka iso_8859_1
. De nombreux fichiers dans les langues d'Asie de l'Est réussissent le premier test avec gb18030
, car les caractères fréquemment utilisés en chinois, japonais et coréen sont codés en utilisant les mêmes blocs de séquences de deux octets. Combien de deuxième test avez-vous fait? Ne cherchez pas les données dans un IDE ou un éditeur de texte. Regardez-le dans un navigateur Web; ils font généralement un meilleur travail de détection des encodages.
Comment savez-vous que c'est un caractère Euro? En regardant l'écran d'un éditeur de texte qui décode les octets bruts en utilisant quel encodage? cp1252?
Comment savez-vous qu'il contient des caractères chinois? Es-tu sûr que ce n'est pas japonais? Coréen? Où est-ce que tu l'as trouvé?
Les fichiers chinois créés à Hong Kong, à Taiwan, peut-être à Macao, et dans d'autres endroits au large du continent utilisent le codage big5
ou big5_hkscs
- essayez-le.
Dans tous les cas, prenez l'avis de Mark et pointez le chardet
dessus; chardet
fait généralement un assez bon travail de détection de l'encodage utilisé si le fichier est assez grand et correctement encodé en chinois/japonais/coréen - cependant si quelqu'un a modifié manuellement le fichier dans un éditeur de texte en utilisant un jeu de caractères mono-octet, les caractères non autorisés peuvent provoquer l'encodage utilisé pour les autres 99,9% des caractères à ne pas détecter.
Vous pouvez faire print repr(line)
sur 5 lignes du fichier et éditer la sortie dans votre question.
Si le fichier n'est pas confidentiel, vous pouvez le rendre disponible au téléchargement.
Le fichier a-t-il été créé sous Windows? Comment le lisez-vous en Python? (Code spectacle)
Mise à jour après les commentaires OP:
Bloc-notes etc ne pas essayer de deviner l'encodage; "ANSI" est la valeur par défaut. Vous devez lui dire quoi faire. Ce que vous appelez le caractère Euro est l'octet brut "\ x80" décodé par votre éditeur en utilisant l'encodage par défaut pour votre environnement - le suspect habituel étant "cp1252". N'utilisez pas un tel éditeur pour éditer votre fichier.
Plus tôt, vous parliez des "premières erreurs". Maintenant vous dites que vous avez 5 erreurs au total. S'il vous plaît, expliquez.
Si le fichier est en effet presque correct gb18030, vous devriez être capable de décoder le fichier ligne par ligne, et quand vous obtenez une telle erreur, piègez-le, imprimez le message d'erreur, extrayez les offsets du message, imprimez repr (two_bad_bytes), et continuez. Je suis très intéressé par lequel des deux octets le \x80
apparaît. S'il n'apparaît pas du tout, le "caractère Euro" ne fait pas partie de votre problème. Notez que \x80
peut apparaître valablement dans un fichier gb18030, mais seulement comme le deuxième octet d'une séquence de 2 octets commençant par \x81
à \xfe
.
C'est une bonne idée de savoir quel est votre problème avant d'essayer de le réparer. Essayer de le résoudre en le dénigrant avec Notepad etc en mode "ANSI" n'est pas une bonne idée.
Vous avez été très timide sur la façon dont vous avez décidé que les résultats du décodage gb18030 avaient du sens. En particulier je scruterai de près les lignes où gbk échoue mais gb18030 "fonctionne" - il doit y avoir des caractères chinois extrêmement rares, ou peut-être des caractères non-chinois non-ASCII ...
Voici une suggestion Pour une meilleure façon d'inspecter les dommages: décoder chaque fichier avec raw_bytes.decode(encoding, 'replace')
et écrire le résultat (encodé dans utf8) dans un autre fichier. Comptez les erreurs par result.count(u'\ufffd')
. Voir le fichier de sortie avec tout ce que vous avez utilisé pour décider que le décodage gb18030 fait sens. Le caractère U + FFFD devrait apparaître comme un point d'interrogation blanc à l'intérieur d'un diamant noir.
Si vous décidez que les pièces indécodables peuvent être mis au rebut, le plus simple est raw_bytes.decode(encoding, 'ignore')
Mise à jour après de plus amples informations
Tous les \\
sont confus. Il semble que "obtenir les octets" implique repr(repr(bytes))
au lieu de seulement repr(bytes)
...à l'invite interactive, effectuez bytes
(vous obtiendrez un Repr implict()) ou print repr(bytes)
(qui ne se la rééd implicite())
L'espace vide: Je suppose que vous voulez dire que '\xf8\xf8'.decode('gb18030')
est ce que vous interprétez comme une sorte d'espace de pleine largeur, et que l'interprétation est faite par une inspection visuelle en utilisant un logiciel de visionneuse innommable. Est-ce exact? En réalité, '\xf8\xf8'.decode('gb18030')
->u'\e28b'
. U + E28B se trouve dans la PUA Unicode (zone d'utilisation privée). L '"espace vide" signifie probablement que le logiciel de visualisation n'a pas de glyphe pour U + E28B dans la police qu'il utilise. La source des fichiers est peut-être délibérément l'utilisation de PUA pour les caractères qui ne sont pas en gb18030 standard, ou pour l'annotation, ou pour transmettre des informations pseudosecret. Si oui, vous aurez besoin de recourir au tambourin de décodage, une émanation de la recherche russe récente reported here.
Alternative: la théorie cp939-HKSCS. Selon le gouvernement HK, le code big5 de HKSCS FE57 a été mis en correspondance avec U + E28B mais est maintenant mappé sur U + 28804. Le "euro": Vous avez dit "" "En raison des données je ne peux pas partager toute la ligne, mais ce que j'appelais l'euro char est: \ xcb \ xbe \ x80 \ x80" [I ' m en supposant qu'un \
a été omis au début de cela, et le "
est littéral]. Le "caractère euro", quand il apparaît, est toujours dans la même colonne que je n'ai pas besoin, alors j'espérais simplement utiliser "ignorer". Malheureusement, puisque le "euro char" est juste à côté des citations dans le fichier, parfois "ignore" se débarrasse à la fois du caractère euro et des guillemets, ce qui pose un problème au module csv pour déterminer les colonnes "" "
Il serait énormément utile si vous pouviez montrer les modèles d'où ces \x80
octets apparaissent en relation avec les guillemets et les caractères chinois - gardez-le lisible en montrant juste l'hex, et cacher vos données confidentielles par exemple en utilisant C1 C2 à représentent « deux octets que je représente que un caractère chinois » par exemple:.
C1 C2 C1 C2 cb be 80 80 22 # `\x22` is the quote character
S'il vous plaît fournir des exemples de (1) où le "ne se perd pas par « remplacer » ou « ignorer »(2) où le citation est perdue. Dans votre seul exemple à ce jour, le "n'est pas perdu.
>>> '\xcb\xbe\x80\x80\x22'.decode('gb18030', 'ignore')
u'\u53f8"'
Et l'offre de vous envoyer un code de débogage (voir l'exemple de sortie ci-dessous) est toujours ouverte
>>> import decode_debug as de
>>> def logger(s):
... sys.stderr.write('*** ' + s + '\n')
...
>>> import sys
>>> de.decode_debug('\xcb\xbe\x80\x80\x22', 'gb18030', 'replace', logger)
*** input[2:5] ('\x80\x80"') doesn't start with a plausible code sequence
*** input[3:5] ('\x80"') doesn't start with a plausible code sequence
u'\u53f8\ufffd\ufffd"'
>>> de.decode_debug('\xcb\xbe\x80\x80\x22', 'gb18030', 'ignore', logger)
*** input[2:5] ('\x80\x80"') doesn't start with a plausible code sequence
*** input[3:5] ('\x80"') doesn't start with a plausible code sequence
u'\u53f8"'
>>>
Eureka: - Cause probable de perdre parfois le caractère de citation -
il semble qu'il y ait un bug dans le décodeur gb18030
remplacer/mécanisme ignorer: \x80
n'est pas un octet de plomb GB18030 valide, quand il est de détecter ed le décodeur doit tenter de resynchroniser avec l'octet NEXT. Cependant, il semble ignorer à la fois l'\x80
et l'octet suivant:
>>> '\x80abcd'.decode('gb18030', 'replace')
u'\ufffdbcd' # the 'a' is lost
>>> de.decode_debug('\x80abcd', 'gb18030', 'replace', logger)
*** input[0:4] ('\x80abc') doesn't start with a plausible code sequence
u'\ufffdabcd'
>>> '\x80\x80abcd'.decode('gb18030', 'replace')
u'\ufffdabcd' # the second '\x80' is lost
>>> de.decode_debug('\x80\x80abcd', 'gb18030', 'replace', logger)
*** input[0:4] ('\x80\x80ab') doesn't start with a plausible code sequence
*** input[1:5] ('\x80abc') doesn't start with a plausible code sequence
u'\ufffd\ufffdabcd'
>>>
Pouvez-vous demander à la source de la csv comment elle est encodée? – Daenyth
Malheureusement, non. – rallen
Lorsque vous avez ouvert le fichier dans votre éditeur de texte, tous les caractères s'affichaient-ils correctement? Quel encodage votre éditeur de texte a-t-il pensé? –