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). Какую кодировку угадал браузер [обычно достоверно]?

Другие возможные ключи кодировки: Какие языки используются в тексте в файлах? Где вы взяли файлы?

Примечание: пожалуйста, отредактируйте свой вопрос с уточняющей информацией; не отвечайте в комментариях.

Другие вопросы по тегам