Питер Пайпер передал программу Python и потерял все свои символы в Юникоде - программирование
Подтвердить что ты не робот

Питер Пайпер передал программу Python и потерял все свои символы в Юникоде

У меня есть Python script, который загружает веб-страницу с помощью urllib2.urlopen, выполняет некоторые различные магии и выплевывает результаты с помощью print. Затем мы запускаем программу на Windows следующим образом:

python program.py > output.htm

Здесь проблема:

urlopen считывает данные с веб-сервера IIS, который выводит UTF8. Он выводит эти же данные на выход, но некоторые символы (например, длинный дефис, который Word всегда вставляет для вас против вашей воли, потому что он умнее вас) искажается и заканчивается, например, â€".

После дальнейшего изучения я заметил, что даже если веб-сервер выплевывает данные UTF8, файл output.htm кодируется набором символов ISO-8859-1.

Мои вопросы:

  • Когда вы перенаправляете программу Python в выходной файл в Windows, всегда ли используется этот набор символов?
  • Если да, есть ли способ изменить это поведение?
  • Если нет, есть ли обходной путь? Полагаю, я мог бы просто передать output.htm в качестве параметра командной строки и записать в этот файл вместо экрана, но мне пришлось бы переделать целую кучу логики в моей программе.

Спасибо за любую помощь!

UPDATE:

В верхней части output.htm я добавил:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Однако это не имеет значения. Символы все еще искажены. Если я вручную переключусь на UTF-8 в Firefox, файл отобразится правильно. И IE, и FF считают, что этот файл является западным ISO, хотя это явно не так.

4b9b3361

Ответ 1

Из ваших комментариев и обновления вопроса кажется, что данные правильно закодированы в UTF-8. Это означает, что вам просто нужно указать вашему браузеру UTF-8, либо используя спецификацию, либо лучше, добавив информацию о кодировке в свой HTML-документ:

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>

Вам действительно не следует использовать объявление XML, если документ не является допустимым XML.

Лучшим и надежным способом будет служить файл через HTTP и соответствующим образом установить заголовок Content-Type:.

Ответ 2

Когда вы подключаете программу Python к выходному файлу в Windows, всегда ли используется этот набор символов?

Кодировка по умолчанию, используемая для вывода в канал. На моей машине:

In [5]: sys.getdefaultencoding()
Out[5]: 'ascii'

Если нет, есть ли обходной путь?

import sys
try:
    sys.setappdefaultencoding('utf-8')
except:
    sys = reload(sys)
    sys.setdefaultencoding('utf-8')

Теперь весь вывод кодируется в 'utf-8'.

Я думаю, что правильный способ справиться с этой ситуацией без

повторить целую кучу логики

- декодировать все данные из вашего интернет-источника с сервера или страницы на unicode, а затем использовать обходное решение, показанное выше, для установки кодировки по умолчанию на utf-8.

Ответ 3

Большинство программ под Windows предполагают, что вы используете стандартную кодировку Windows, которая будет ISO-8859-1 для английской установки. Это также относится к выходному окну командной строки. Невозможно установить кодировку по умолчанию для UTF-8, к сожалению, - для нее определена кодовая страница, но она не поддерживается.

Некоторые редакторы распознают любые символы спецификации в начале файла и переключаются на UTF-8, но это не гарантируется.

Если вы создаете HTML, вы должны указать правильный тег charset; то браузер правильно интерпретирует его.