Проблема с кодировкой и urllib - PullRequest
1 голос
/ 14 мая 2010

Я загружаю веб-страницу, используя urllib.Есть русские символы, но кодировка страницы - utf-8

1

pageData = unicode(requestHandler.read()).decode('utf-8')

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 262: ordinal not in range(128)

2

pageData = requestHandler.read()
soupHandler = BeautifulSoup(pageData)
print soupHandler.findAll(...)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 340-345: ordinal not in range(128)

Ответы [ 2 ]

2 голосов
/ 14 мая 2010

В вашем первом фрагменте вызов unicode(requestHandler.read()) говорит Python преобразовать строку байтов, возвращаемую read в unicode: так как для преобразования не указан код, ascii проверяется (и не выполняется). Он никогда не доходит до того, что вы собираетесь вызывать .decode (что в любом случае не имеет смысла вызывать этот юникод-объект).

Либо используйте unicode(requestHandler.read(), 'utf-8'), или requestHandler.read().decode('utf-8'): любой из них должен создать правильный объект Unicode , если кодировка действительно utf-8 (наличие этого D0 байт предполагает, что это может быть не так, но невозможно угадать, если из контекста показывать один не-ascii символ).

print ing Данные Unicode - это другая проблема, для которой требуется хорошо сконфигурированный и совместимый эмулятор терминала - тот, который позволяет Python устанавливать sys.stdout.encoding при запуске. Например, на Mac, используя терминал Apple. Приложение :

>>> sys.stdout.encoding
'UTF-8'

, поэтому печать объектов Unicode работает нормально:

>>> print u'\xabutf8\xbb'
«utf8»

как и печать байтовых строк в кодировке utf8:

>>> print u'\xabutf8\xbb'.encode('utf8')
«utf8»

но на других машинах будет работать только последняя (используя собственную кодировку эмулятора терминала, которую вам нужно выяснить самостоятельно, потому что эмулятор терминала не говорит Python; -).

1 голос
/ 14 мая 2010

Если requestHandler.read() доставляет поток в кодировке UTF-8, тогда

pageData = requestHandler.read().decode('utf-8')

декодирует это в строку Unicode (в этот момент, как правильно заметил Дитрих Эпп), вызов unicode() больше не нужен.

Если выдается исключение, то, очевидно, вход не кодируется в UTF-8.

...