Питер Пайпер записал программу на Python - и потерял все свои символы юникода - PullRequest
16 голосов
/ 06 января 2012

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

python program.py > output.htm

Вот проблема:

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

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

Мои вопросы:

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

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

ОБНОВЛЕНИЕ:

Вверху 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, хотя это явно не так.

Ответы [ 3 ]

8 голосов
/ 06 января 2012

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

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

Вы действительно не должны использовать декларацию XMLесли документ не является допустимым XML.

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

5 голосов
/ 06 января 2012

Когда вы передаете программу 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'.

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

повторить aВся логика

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

2 голосов
/ 06 января 2012

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

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

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

...