Вопрос: проблема с декодированием Unicode


Это смешно .. Я пытаюсь читать данные географического поиска из openstreetmap. Код, выполняющий запрос, выглядит так:

params = urllib.urlencode({'q': ",".join([e for e in full_address]), 'format': "json", "addressdetails" : "1"})
query = "http://nominatim.openstreetmap.org/search?%s" % params
print query
time.sleep(5)
response = json.loads(unicode(urllib.urlopen(query).read(), "UTF-8"), encoding="UTF-8")
print response

Запрос для Zürich корректно кодируется URL-адресами по данным UTF-8. Здесь нет чудес.

http://nominatim.openstreetmap.org/search?q=Z%C3%BCrich%2CSWITZERLAND&addressdetails=1&format=json

Когда я печатаю ответ, u с umlaut кодируется latin1 (0xFC)

[{u'display_name': u'Z\xfcrich, Bezirk Z\xfcrich, Z\xfcrich, Schweiz, Europe', u'place_id': 588094, u'lon': 8.540443

но это глупость, потому что openstreetmap возвращает данные JSON в UTF-8

Connecting to nominatim.openstreetmap.org (nominatim.openstreetmap.org)|128.40.168.106|:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Date: Wed, 26 Jan 2011 13:48:33 GMT
  Server: Apache/2.2.14 (Ubuntu)
  Content-Location: search.php
  Vary: negotiate
  TCN: choice
  X-Powered-By: PHP/5.3.2-1ubuntu4.7
  Access-Control-Allow-Origin: *
  Content-Length: 3342
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Content-Type: application/json; charset=UTF-8
Length: 3342 (3.3K) [application/json]

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

Что тут происходит ?

РЕДАКТИРОВАТЬ  : видимо, это json.loads, который как-то завинчивается.


4


источник


Ответы:


Когда я иду и печатаю ответ,   u с umlaut кодируется latin1 (0xFC)

Вы просто неправильно интерпретируете вывод. Это строка в Юникоде (вы можете указать в префиксе u), нет кодировки «прикреплено» - это означает, что \ xFC означает, что это код с номером 0xFC, который, как представляется, является U-Umlaut (см. http://www.fileformat.info/info/unicode/char/fc/index.htm ). Причина этого в том, что нумерация первых 256 кодов Unicode совпадает с латинской кодировкой.

Короче говоря, вы сделали все правильно - у вас есть объект unicode с нужным контентом (который не зависит от кодировок), вы можете выбрать нужную кодировку, когда вы используете этот контент для вывода где-то, выполнив unicodestr.encode («utf-8 ") или с помощью кодеков, см. http://docs.python.org/howto/unicode.html#reading-and-writing-unicode-data


8



Выход прекрасен. Всякий раз, когда вы печатаете данные на консоли, Python учитывает Unicode данные только при печати фактической строки. Если вы печатаете список юникодов, каждая строка юникода отображается на консоли как ее функция repr ():

>>> a=u'á'
>>> a
u'\xe1'
>>> print a
á
>>> [a]
[u'\xe1']
>>> print [a]
[u'\xe1']

1