2013-02-27 1 views
1

일부 지리 데이터를 Python의 simplejson으로로드하려고합니다.simplejson : 로딩 스페인어 문자 - utf-8

<!-- 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"}}]]} 

파이썬은 나에게 오류 simplejson.decoder.JSONDecodeError: Expecting object


내가 prCounties.txt를 생성하는 GitHub의에서로드하는 데 사용되는 스크립트를 제공합니다. 변수 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)) 

편집 : 마지막 라인에, 내가 simplejson.dumpsstr를 교체했다. 나는 그것이 지금 적절하게 암호화한다고 생각한다. 파일 ("prCounties.txt", "w") write (simplejson.dumps (d))

+0

'u는 "A가 xf1asco \"'같은 문자열'과 같다 : 그럼 당신은)합니다 (simplejson.loads 읽을 기능 형식으로 변수 "문자열"을 만들기 위해 잘 작동이 코드를 사용할 수 있습니다 u "Añasco"(및 "u"A \ u00f1asco "). – abarnert

+0

당신이'u '로 보는 이유는 \ xf1asco "'(파이썬 2.x에서) 유니 코드 문자열의'repr'이 비 ASCII 문자를 이스케이프한다는 것입니다. 예를 들어, 인터프리터 인터프리터에서'u'''''''는'u' \ xf1''을 출력하지만'print''''''는'ñ'를 출력합니다. – abarnert

+0

또 다른 이유는 simplejson이 제대로로드되지 않았기 때문입니까? –

답변

2

이 두 가지 문제는 여기에있다. 우선 :

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

왜 디코딩하나요? JSON은 명시 적으로 UTF-8 문자열을 사용합니다. 이것이 JSON 정의의 일부입니다. simplejson이 유니 코드 문자열을 처리 할 수 ​​있다는 사실 때문에 사용하기가 좀 더 쉬워졌습니다. 그러나 UTF-8로 인코딩하여 효과적으로 처리하므로 ... 처음부터 그렇게하지 않는 이유는 무엇입니까?

더 중요한 것은 데이터가 어디서 왔습니까? prCounties.txtu"Añasco"이 있으면 JSON이 아닙니다. 비슷한 것으로 보아 완전히 다른 표준으로 무언가를 인코딩하고 디코딩 할 수는 없습니다.

예를 들어 open('prCounties.txt', 'w').write(repr(my_dict))을 작성한 경우 파이어 repr 파서로 다시 읽어야합니다 (아마도 ast.literal_eval이거나 직접 작성해야합니다).

또는 JSON으로 데이터를 구문 분석하려면 먼저 JSON으로 작성하십시오.


는 귀하의 의견에 따르면, 데이터 https://raw.github.com/johan/world.geo.json/master/countries/USA/PR /Añasco.geo에서 읽었습니다.JSON

해당 URL의 원시 내용은 다음과 같습니다

{"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", 또는 아무것도)가없는 것을 알 수 있습니다. 당신은 UTF-8에서 디코딩 아무것도 - 그냥 simplejson.loads에 전달할 필요가 아니 read를 호출하여 이것을 읽을 수 있으며, 그것은 잘 작동 :

$ 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.loadsreprdict을 다시 시도했습니다. 또는 이미 인코딩 된 JSON 문자열로 가득 찬 dict을 JSON으로 인코딩했을 수도 있습니다. 어떤 코드를 작성 했든, 코드는 우리에게 보여주고있는 코드가 아니라 오류의 위치입니다.

가장 쉬운 수정은 아마도 처음에는 prCounties.txt을 적절하게 생성하는 것입니다. 그것은 단지 몇 줄을 하나씩 다운로드하는 것일뿐입니다. 단지 2 줄의 bash 또는 4 줄의 파이썬이 필요합니다 ...

+0

'https : // github.com/johan/world.geo.json/blob/master/countries/USA/PR/Añasco.geo.json' 파일 이름과 텍스트에'ñ'가 있습니다. –

+0

예, 내용에 '...'name ":"Añasco ", '가 있습니다. 네가 네 이름을 어디에서 얻었 니? : u "Añasco"... "? 파일에 대해 일종의 처리를 수행하여 JSON을 비 JSON으로 변환했습니다. 파일에서 실제 원시 데이터를 구문 분석하면 정상적으로 작동합니다. – abarnert

+0

흠 ... 나는'urllib.urlopen'을 사용하여 Github에서 그것을 읽고 (약 75 개의 비슷한 파일들), 하나의 파일로 합치고 저장했습니다. 그 파일을 열면이 혼란이 시작되었습니다. –

2

입력 파일이 유효한 JSON이 아닙니다. "A\xf1asco" 문자열 앞에 u이 있습니다.이 문자열은 JSON 구문이 아니라 Python 구문입니다. 그것은해야한다 :

"name":"A\xf1asco", 

이 작동 :

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

+1. 그러나 당신은 외부'u'를 필요로하지 않습니다; 일반적으로 JSON을 UTF-8로 얻습니다. 예를 들어,'{ 'name': u'Anasco '}'를 JSON으로 인코딩하면'{ "name": "A \ xc3 \ xb1asco"}'를 얻게 될 것이고 그것은 똑같은 것으로 디코딩 할 것입니다 . (다른 말로하면,'json.loads'는 실제로 그것을 디코딩하기 전에 당신이 입력 한'encode ('utf-8')'을 호출하고 있습니다.) – abarnert

+0

json 디코드가 정상적으로 작동했지만 OP가 파이썬 리터럴을보고 있습니다. –

+0

@MartijnPieters : OP에서 "simplejson.decoder.JSONDecodeError"가 표시된다고합니다. 어쩌면 그는 JSON 디코딩을 시도하고 결과 또는 다른 것을 다시 JSON 디코딩 할 것입니다. – abarnert

0

prCounties.txt 파일에서 "u"를 제거해야합니다. 이미 말한).

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