Путаница с юникодом в Python - PullRequest
1 голос
/ 09 мая 2011

В рамках сайта Django пользователи могут вводить названия улиц, и эта запись будет добавлена ​​в ссылку геокодирования карт Google.Все работает хорошо, пока пользователи не введут специальные символы.

Я бы хотел отобразить специальный символ в ссылке, однако python заменяет этот символ на символ Unicode. Есть ли способ предотвратить переход Python на Unicode и просто принимать ввод от пользователя? Я пробовал несколько декодеров и форматов, но это не решило проблему.

edit: Кодзапрограммирован в Python 2.

В настоящее время я запрашиваю ответ JSON следующим образом:

    url = "http://maps.googleapis.com/maps/api/geocode/json?address=" +
          addressString.decode('ascii') + "&sensor=false";
    googleResponse = urllib.urlopen(url);

Спасибо за вашу помощь и совет.

Ответы [ 3 ]

5 голосов
/ 09 мая 2011

Во-первых, проверьте, является ли addressString объектом Unicode (это если вы используете Python 3 или type(addressString) показывает 'Unicode').Если это так, то вам, вероятно, нужно попробовать следующее:

url = "http://maps.googleapis.com/maps/api/geocode/json?address=" +
      urllib.quote(addressString.encode('utf-8')) + "&sensor=false";

Если addressString является (не-Unicode) строковым объектом (в Python 2) или байтовым объектом (в Python 3),должен быть уже закодирован в UTF-8.В этом случае попробуйте следующее:

url = "http://maps.googleapis.com/maps/api/geocode/json?address=" +
      urllib.quote(addressString) + "&sensor=false";

Оба эти фрагмента должны преобразовывать символы Юникода в escape-последовательности URL-адресов с использованием знаков %.Это стандартный способ использования не-ASCII символов в URL.Современные браузеры должны декодировать эти последовательности, отображая их как символы Юникода.

2 голосов
/ 10 мая 2011

[большой жирный комментарий, потому что комментарии не могут быть хорошо отформатированы]

Следуя инструкциям @Boaz Yaniv, у меня работает:

>>> addressString = 'Wilhelmstra\xc3\x9fe 123, T\xc3\xbcbingen, Deutschland'

Это str объект, закодированный в UTF-8. Нам нужно избегать процентов, чтобы его можно было использовать в URL.

>>> import urllib
>>> fixed = urllib.quote(addressString)
>>> print repr(fixed)
'Wilhelmstra%C3%9Fe%20123%2C%20T%C3%BCbingen%2C%20Deutschland'

Теперь давайте попробуем:

>>> url = "http://maps.googleapis.com/maps/api/geocode/json?address=" + fixed +
"&sensor=false"
>>> guff = urllib.urlopen(url).read()
>>> import json
>>> print repr(json.loads(guff)['results'][0]['formatted_address'])
u'Wilhelmstra\xdfe 123, 72074 T\xfcbingen, Germany'
>>>

Если у вас есть что-то вроде этого: 'Wilhelmstra\xdfe 123, T\xfcbingen, Deutschland', это объект str, закодированный в latin1 или cp1252 или как угодно. Вам нужно будет декодировать это в unicode объект, затем кодировать это в UTF-8, а затем экранировать в процентах.

Однако, если у вас есть (ОЧЕНЬ тонкая разница) u'Wilhelmstra\xdfe 123, T\xfcbingen, Deutschland', это объект unicode, и вам нужно будет его кодировать в UTF-8, а затем избегать процентов.

Вы сказали "" " я все еще получаю то же сообщение об ошибке: Тип исключения: UnicodeEncodeError Значение исключения: кодек «ascii» не может кодировать символ u '\ xdf' в позиции 10: порядковый номер не в диапазоне (128) при запросе ссылки "" "

Похоже, вы подаете объект unicode чему-то, что хочет объект str и пытается получить его путем кодирования с использованием (обычно по умолчанию) ascii кодирования. Если проблема не устранена, покажите свой код. Разбейте его до необходимого минимума (как я делал выше). Показать репр (step_by_step_results).

0 голосов
/ 09 мая 2011

Не уверен, попробуйте:

url = "http://maps.googleapis.com/maps/api/geocode/json?address=" +
addressString.decode ('utf-8') +" & sensor = false ";
googleResponse = urllib.urlopen (URL);

...