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-файла в парсер. Модульный тест действительно ожидает, что это произойдет. Парсер должен распознать это как нечто, что не поддается синтаксическому анализу. Итак, мне нужно изменить обработку исключений. В процессе этого сейчас.


person Aaron Altman    schedule 19.07.2010    source источник


Ответы (3)


Позиция 0x81 не назначена в Windows-1252 (также известна как cp1252). Ему присваивается управляющий символ U + 0081 HIGH OCTET PRESET (HOP) в Latin-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, как предлагается в кодовой записи:

>>> open('test.txt', encoding='latin-1').read()
'\x81\n'

Помните, что существуют различия между кодировками Windows-1257 и Latin-1, например Latin-1 не имеет «умных кавычек». Если файл, который вы обрабатываете, является текстовым файлом, спросите себя, что делает в нем этот \ x81.

person Marius Gedminas    schedule 19.07.2010
comment
FWIW Latin-1 имеет все 256 назначенных кодовых точек, поэтому вы никогда не получите UnicodeDecodeError. Но вы можете повредить свои данные. - person Marius Gedminas; 20.07.2010

Вы можете облегчить обработку ошибок.

Например:

f = open(filename, encoding="...", errors="replace")

Or:

f = open(filename, encoding="...", errors="ignore")

См. документы.

РЕДАКТИРОВАТЬ:

Но уверены ли вы, что проблема в чтении файла? Может ли быть исключение, когда что-то записывается в консоль? Проверьте http://wiki.python.org/moin/PrintFails.

person codeape    schedule 19.07.2010
comment
Я попробовал оба варианта с одинаковыми результатами. Ошибка возникает до того, как произойдет вывод. - person Aaron Altman; 20.07.2010
comment
-1 ослабить обработку ошибок, не имея ни малейшего представления о том, что игнорируется и почему - бездумная бойня - person John Machin; 20.07.2010
comment
Действительно, игнорирование ошибок кодирования является плохой практикой и нарушает стандарт Unicode. - person Philipp; 20.07.2010
comment
@altie: Вероятно, ошибка связана с записью чего-то в консоль. - person codeape; 22.07.2010
comment
спасибо, это было очень полезно. Моя ситуация заключалась в том, что у меня есть текстовые журналы с очень редкими двоичными данными, и я хотел использовать регулярное выражение и обрабатывать их. - person jnnnnn; 19.03.2013

Все файлы не в Юникоде. Юникод - это внутреннее представление, которое необходимо закодировать. Вам необходимо определить для каждого файла, какая кодировка была использована, и указать это, где это необходимо, при открытии файла.

Как указано в трассировке и сообщении об ошибке, рассматриваемый файл НЕ закодирован в cp1252.

Если он закодирован в latin1, "\x81", на который он жалуется, является управляющим символом C1, у которого даже нет имени (в Unicode). Считайте latin1 крайне маловероятным.

Вы говорите «некоторые файлы анализируются с помощью xml.dom.minidom» - проанализированы успешно или безуспешно?

В допустимом XML-файле должна быть указана его кодировка (по умолчанию UTF-8) в первой строке, и вам не нужно указывать кодировку в вашем коде. Покажите нам код, который вы используете для синтаксического анализа xml.dom.minidom.

«другие читаются напрямую как итерации» - пример кода, пожалуйста.

Предложение: попробуйте открыть в браузере несколько файлов каждого типа. Затем нажмите «Просмотр» и нажмите «Кодировка символов (Firefox) или Кодировка (Internet Explorer)». Какую кодировку браузер угадал [обычно надежно]?

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

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

person John Machin    schedule 19.07.2010
comment
Возможно, это кодовая страница DOS, в которой '\ x81' обычно означает 'ü'. - person dan04; 20.07.2010