simplejson:加载西班牙语字符 - utf-8

时间:2013-02-27 21:25:25

标签: python json internationalization simplejson

我正在尝试使用Python simplejson加载一些地理数据。

<!-- language: lang-py -->
string = file("prCounties.txt","r").read().decode('utf-8')  
d = simplejson.loads(string)    

文本文件有一个波浪号,这个词应该是Añasco,而不是SimpleJson没有解析的u"A\xf1asco"。来源是geoJson file from github

{"type": "FeatureCollection", "properties": {"kind": "state", "state": "PR"}, "features": [[{"geometry": {"type": "MultiPolygon", "coordinates": [[[[-67.122, 18.3239], [-67.0508, 18.3075], [-67.0398, 18.291], [-67.0837, 18.2527], [-67.122, 18.2417], [-67.1603, 18.2746], [-67.1877, 18.2691], [-67.2261, 18.2965], [-67.1822, 18.3129], [-67.1275, 18.3184]]]]}, "type": "Feature", "properties": {"kind": "county", "name": u"A\xf1asco", "state": "PR"}}]]}

Python给了我错误simplejson.decoder.JSONDecodeError: Expecting object


我用来从GitHub加载以生成prCounties.txt的脚本。变量counties是与相关GEOjson数据的位置相关的字符串列表。

很明显,这不是保存此数据的正确方法:

<!-- language: lang-py -->
countyGeo = [ ]

for x in counties:      
    d = simplejson.loads(urllib.urlopen("https://raw.github.com/johan/world.geo.json/master/countries/USA/PR/%s" % (x)).read())         
    countyGeo += [ d["features"][0]]
    d["features"][0]=countyGeo  
file("prCounties.txt", "w").write(str(d))

编辑:在最后一行,我将str替换为simplejson.dumps。我想它现在正确编码。     file(“prCounties.txt”,“w”)。write(simplejson.dumps(d))

3 个答案:

答案 0 :(得分:2)

您的输入文件无效JSON。在u字符串之前有一个"A\xf1asco",它是Python语法,而不是JSON语法。它应该是:

"name":"A\xf1asco",

这有效:

>>> import json
>>> json.loads(u'{"name":"A\xf1asco"}')
{u'name': u'A\xf1asco'}

答案 1 :(得分:2)

这里有两个问题。第一:

string = file("prCounties.txt","r").read().decode('utf-8')

你为什么解码它? JSON显式获取UTF-8字符串。这是JSON定义的一部分。 simplejson可以处理Unicode字符串的事实使它更容易使用,但它通过将它们编码回UTF-8来有效地处理它们,所以......为什么不把它放在第一位?

更重要的是,您的数据来自哪里?如果prCounties.txt中包含u"Añasco",那么它不是JSON。您不能将某些内容编码为一个标准,并且只是因为它们看起来相似而解码为完全不同的标准。

例如,如果您执行了open('prCounties.txt', 'w').write(repr(my_dict)),则必须使用Python repr解析器(可能是ast.literal_eval)来阅读它,或者您可能需要自己编写一些内容。< / p>

或者,或者,如果要将数据解析为JSON,请首先将其写为JSON。


根据您的评论,数据来自https://raw.github.com/johan/world.geo.json/master/countries/USA/PR /Añasco.geo.json

该网址的原始内容为:

{"type":"FeatureCollection","properties":{"kind":"state","state":"PR"},"features":[
{"type":"Feature","properties":{"kind":"county","name":"Añasco","state":"PR"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-67.1220,18.3239],[-67.0508,18.3075],[-67.0398,18.2910],[-67.0837,18.2527],[-67.1220,18.2417],[-67.1603,18.2746],[-67.1877,18.2691],[-67.2261,18.2965],[-67.1822,18.3129],[-67.1275,18.3184]]]]}}
]}

您会注意到那里没有"name": u"Añasco"(或"name": u"A\xf1asco"或类似的东西)。您只需致电read即可阅读本文 - 无需从UTF-8或其他任何内容解码 - 只需将其传递给simplejson.loads即可正常使用:

$ curl -O https://raw.github.com/johan/world.geo.json/master/countries/USA/PR/Añasco.geo.json
$ cp Añasco.geo.json prCounties.txt
$ python
>>> import simplejson
>>> string = file("prCounties.txt","r").read()
>>> d = simplejson.loads(string)
>>> print d
{u'type': u'FeatureCollection', u'properties': {u'kind': u'state', u'state': u'PR'}, u'features': [{u'geometry': {u'type': u'MultiPolygon', u'coordinates': [[[[-67.122, 18.3239], [-67.0508, 18.3075], [-67.0398, 18.291], [-67.0837, 18.2527], [-67.122, 18.2417], [-67.1603, 18.2746], [-67.1877, 18.2691], [-67.2261, 18.2965], [-67.1822, 18.3129], [-67.1275, 18.3184]]]]}, u'type': u'Feature', u'properties': {u'kind': u'county', u'name': u'A\xf1asco', u'state': u'PR'}}]}

看,根本没有错误。

在某个地方,你已经对这些数据做了些什么,把它变成了一些不是JSON的东西。我的猜测是,除了做一堆不必要的额外decodeencode来电之外,你还做了simplejson.loads,然后尝试重新simplejson.loads你回来的repr dict。或者你可能已经JSON编码了dict个已经编码过的JSON字符串。无论你做了什么,代码,而不是你向我们展示的代码,都是错误的地方。

最简单的修复方法可能是首先正确生成prCounties.txt。这只是每行几行的70多次下载,它可能需要2行bash或4行Python才能完成......

答案 2 :(得分:0)

您必须删除prCounties.txt文件中的“u”(已经说过)。然后你可以使用这个代码,它可以用simplejson.loads()函数可读的格式创建变量“string”:

import simplejson
string = file("prCounties.txt", "r").read().decode("string-escape")
string = unicode(string, "latin-1")
simplejson.loads(string)