2011-01-26 12 views
4

これは面白いです。私は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 

クエリはUTF-8データで正しくURLエンコードされます。ここには不思議はない。

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

I応答を印刷すると、ウムラウト付きuが符号化されるLATIN1(0xFC)

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

しかしOpenStreetMapのは、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] 

にJSONデータを返すため、それは無意味ですこれはファイルの内容によっても確認されます。そして、私は、読み取りとjsonの両方の解析でUTF-8であると明示しています。

ここでは何が起こっていますか?

EDIT:明らかに、それは何とかネジ止めされているjson.loadsです。ウムラウト付き

答えて

8

私が行くと回答を印刷し、 uが(0xFC)latin1の符号化されている

あなただけの出力を誤って解釈しています。これはUnicode文字列です(接頭辞ではUで分かります)。エンコーディングは「添付」されていません。\ xFCは、U-Umlaut(http://www.fileformat.info/info/unicode/char/fc/index.htmを参照してください)という0x34のコードポイントを意味します。これが発生する理由は、最初の256のUnicodeコードポイントの番号付けがlatin1のコード化と一致するためです。

つまり、正しいコンテンツ(エンコーディングには無関係)を持つユニコードオブジェクトがある場合、unicodestr.encodeを実行することで、そのコンテンツをどこかの出力に使用するときに、そのエンコーディングを選択できます"utf-8")またはコーデックを使用してください。http://docs.python.org/howto/unicode.html#reading-and-writing-unicode-data

+0

@etarionが、それは 'UTF-8(16進数)0xC3 0xBC'がテーブルに述べています。 UTF-8コンテンツで表現されるべきではありませんか?私が間違っていない場合、 'oxFC 'を文字通り取ってUTF-8文字列の文字として使うと無効文字になります。 –

+0

あなたは正しいかもしれません...コードポイントか実際のデータかどうかをどうやって確認できますか?それをASCIIにデコードしようとしますか? –

+0

+1:それはそれのようなものかもしれないと思ったが、私のpython-fuはそれを正しく検証するのに十分ではありません。 UTF8コンソールに 'print u'Z \ xfcrich''と書いてみると、結局正しいことが書かれていました。興味深いもの: – araqnid

1

出力は正常です。コンソールでデータを印刷するときはいつでも、Pythonは実際の文字列を印刷するときにのみUnicodeにデータをエンコードします。あなたはユニコードのリストを印刷する場合、各Unicode文字列は、そののreprとしてコンソール上でshow()である:

>>> a=u'á' 
>>> a 
u'\xe1' 
>>> print a 
á 
>>> [a] 
[u'\xe1'] 
>>> print [a] 
[u'\xe1'] 
関連する問題