Я пишу программу Python (Python 3.3) для отправки некоторых данных на веб-страницу с использованием метода POST. В основном для процесса отладки я получаю результат страницы и отображаю ее на экране с помощью функции print()
.
Код выглядит следующим образом:
conn.request("POST", resource, params, headers)
response = conn.getresponse()
print(response.status, response.reason)
data = response.read()
print(data.decode('utf-8'));
метод HTTPResponse
.read()
возвращает элемент bytes
, кодирующий страницу (который является хорошо сформированным документом UTF-8). Это выглядело нормально, пока я не прекратил использовать IDLE GUI для Windows и вместо этого использовал консоль Windows. На возвращаемой странице есть символ U + 2014 (em-dash), который функция печати хорошо переносит в графическом интерфейсе Windows (я предполагаю, что код страницы 1252), но не находится в консоли Windows (кодовая страница 850). Учитывая поведение strict
по умолчанию, я получаю следующую ошибку:
UnicodeEncodeError: 'charmap' codec can't encode character '\u2014' in position 10248: character maps to <undefined>
Я мог бы исправить это с помощью этого довольно уродливого кода:
print(data.decode('utf-8').encode('cp850','replace').decode('cp850'))
Теперь он заменяет оскорбительный символ "-" на ?
. Не идеальный случай (дефис должен быть лучшей заменой), но достаточно хорош для моей цели.
В моем решении есть несколько вещей, которые мне не нравятся.
- Код уродливый со всем этим декодированием, кодированием и декодированием.
- Он решает проблему только для этого случая. Если я переношу программу на систему с использованием какой-либо другой кодировки (latin-1, cp437, back to cp1252 и т.д.), Она должна распознать целевую кодировку. Это не. (например, при повторном использовании IDLE GUI, emdash также теряется, чего раньше не было)
- Было бы лучше, если бы emdash переводили в дефис вместо опроса.
Проблема не в emdash (я могу придумать несколько способов решить эту проблему), но мне нужно написать надежный код. Я загружаю страницу данными из базы данных и данные могут возвращаться. Я могу предвидеть многие другие конфликтующие случаи: "Á" U + 00c1 (что возможно в моей базе данных) может перевести на CP-850 (DOS/Windows Console encodign для западноевропейских языков), но не в CP-437 (кодировка для США Английский, который по умолчанию используется во многих установках Windows).
Итак, вопрос:
Есть ли более приятное решение, которое делает мой код агностиком из кодирования выходного интерфейса?