Отправить не-ASCII запрос POST в Python? - PullRequest
7 голосов
/ 08 января 2012

Я пытаюсь отправить запрос POST в веб-приложение. Я использую модуль механизации (сама оболочка urllib2). В любом случае, когда я пытаюсь отправить запрос POST, я получаю UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128). Я пытался поставить unicode(string), unicode(string, encoding="utf-8"), unicode(string).encode() и т. Д., Ничего не получалось - либо вернуло ошибку выше, либо TypeError: decoding Unicode is not supported

Я посмотрел другие SO ответы на подобные вопросы, но ни один не помог.

Заранее спасибо!

РЕДАКТИРОВАТЬ : Пример, который выдает ошибку:

prda = "šđćč" #valid UTF-8 characters
prda # typing in python shell 
'\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d'
print prda # in shell
šđćč
prda.encode("utf-8") #in shell
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)
unicode(prda)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal not in range(128)

Ответы [ 3 ]

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

Я предполагаю, что вы используете Python 2.x.

Учитывая объект Unicode:

myUnicode = u'\u4f60\u597d'

закодируйте его, используя utf-8:

mystr = myUnicode.encode('utf-8')

Обратите внимание, что вам нужно явно указать кодировку. По умолчанию он (обычно) использует ascii.

1 голос
/ 08 января 2012

В вашем примере вы используете строковый литерал не-Unicode, содержащий не-ascii символы, в результате чего prda становится строкой байтов .

Для этого Python используетsys.stdin.encoding для автоматического кодирования строки.В вашем случае это означает, что строка кодируется как "utf-8".

Чтобы преобразовать prda в unicode объект, вам необходимо декодировать его, используя соответствующую кодировку:

>>> print prda.decode('utf-8')
šđćč

Обратите внимание, что в скрипте или модуле вы не можете полагаться на python, чтобы автоматически угадывать кодировку - вам необходимо явно отменить кодировку в верхней части файла, например:

# -*- coding: utf-8 -*-

Всякий раз, когда вы сталкиваетесь с ошибками Unicode в Python 2, это очень часто, потому что ваш код смешивает байтовые строки со строками Unicode.Поэтому вы всегда должны проверять, какая строка вызывает ошибку, используя type(string).

Если строковым объектом является <type 'str'>, но вам нужен Unicode, декодируйте , используясоответствующая кодировка.Если строковый объект <type 'unicode'>, но вам нужны байты, кодируйте , используя соответствующую кодировку.

0 голосов
/ 08 января 2012

Вам не нужно заключать символы в unicode вызовы, потому что они уже закодированы :) если что, вам нужно DE -кодировать его, чтобы получить объект Unicode:

>>> s = '\xc5\xa1\xc4\x91\xc4\x87\xc4\x8d'   # your string
>>> s.decode('utf-8')
u'\u0161\u0111\u0107\u010d'
>>> type(s.decode('utf-8'))
<type 'unicode'>

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

Что бы я делал с обычным urllib2 вызов POST, будет использовать urlencode:

>>> from urllib import urlencode
>>> postData = urlencode({'test': s })   # note I'm NOT decoding it
>>> postData
'test=%C5%A1%C4%91%C4%87%C4%8D'
>>> urllib2.urlopen(url, postData)   # etc etc etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...