Python 3 подавляется чтением CP-1252/ANSI
Я работаю над серией парсеров, где я получаю кучу обратных ссылок от моих модульных тестов, таких как:
File "c:\Python31\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 112: character maps to <undefined>
Файлы открываются с помощью open() без лишних аргументов. Могу ли я передать дополнительные аргументы open() или использовать что-то в модуле кодека, чтобы открыть их по-другому?
Это было сделано с кодом, который был написан на Python 2 и преобразован в 3 с помощью инструмента 2to3.
ОБНОВЛЕНИЕ: оказывается, это результат подачи zip-файла в парсер. Модульный тест на самом деле ожидает, что это произойдет. Парсер должен распознавать это как нечто, что не может быть проанализировано. Итак, мне нужно изменить обработку исключений. В процессе это сейчас.
3 ответа
Позиция 0x81 не назначена в Windows-1252 (она же cp1252). Ему присваивается управляющий символ U+0081 HIGH OCTET PRESET (HOP) на латинице 1 (он же ISO 8859-1). Я могу воспроизвести вашу ошибку в Python 3.1 следующим образом:
>>> b'\x81'.decode('cp1252')
Traceback (most recent call last):
...
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 0: character maps to <undefined>
или с фактическим файлом:
>>> open('test.txt', 'wb').write(b'\x81\n')
2
>>> open('test.txt').read()
Traceback (most recent call last):
...
UnicodeDecodeError: 'utf8' codec can't decode byte 0x81 in position 0: unexpected code byte
Теперь для обработки этого файла как Latin-1 вы передаете encoding
аргумент, как предложил codeape:
>>> open('test.txt', encoding='latin-1').read()
'\x81\n'
Помните, что существуют различия между кодировками Windows-1257 и Latin-1, например, Latin-1 не имеет "умных кавычек". Если файл, который вы обрабатываете, является текстовым файлом, спросите себя, что делает в нем \x81.
Вы можете расслабить обработку ошибок.
Например:
f = open(filename, encoding="...", errors="replace")
Или же:
f = open(filename, encoding="...", errors="ignore")
Смотрите документы.
РЕДАКТИРОВАТЬ:
Но вы уверены, что проблема заключается в чтении файла? Может ли быть так, что исключение происходит, когда что-то записывается на консоль? Проверьте http://wiki.python.org/moin/PrintFails
Все файлы не "Unicode". Unicode - это внутреннее представление, которое должно быть закодировано. Вам необходимо определить для каждого файла, какая кодировка использовалась, и указать это при необходимости при открытии файла.
Как показывают трассировка и сообщение об ошибке, рассматриваемый файл НЕ кодируется в cp1252
,
Если это закодировано в latin1
, "\x81"
он жалуется на управляющий символ C1, который даже не имеет имени (в Unicode). Рассматривать latin1
крайне маловероятно, чтобы быть действительным.
Вы говорите "некоторые файлы анализируются с помощью xml.dom.minidom" - анализируется успешно или безуспешно?
Действительный файл XML должен объявить свою кодировку (по умолчанию UTF-8) в первой строке, и вам не нужно указывать кодировку в своем коде. Покажите нам код, который вы используете для анализа xml.dom.minidom.
"другие читают непосредственно как итерируемые" - пример кода, пожалуйста.
Предложение: попробуйте открыть некоторые файлы каждого типа в вашем браузере. Затем нажмите "Вид" и нажмите "Кодировка символов" (Firefox) или "Кодировка" (Internet Explorer). Какую кодировку угадал браузер [обычно достоверно]?
Другие возможные ключи кодировки: Какие языки используются в тексте в файлах? Где вы взяли файлы?
Примечание: пожалуйста, отредактируйте свой вопрос с уточняющей информацией; не отвечайте в комментариях.