2011-08-03 90 views
8

我想根據經緯度從谷歌地球獲得的高程數據,但我不能夠做到這一點。我不知道我做錯了什麼,但我的代碼如下所示。錯誤解析JSON數據時

def getElevation(locations,sensor="true", **elvtn_args): 
    elvtn_args.update({ 
     'locations': locations, 
     'sensor': sensor 
    }) 

    url = ELEVATION_BASE_URL 
    params = urllib.parse.urlencode(elvtn_args) 
    baseurl = url +"?"+ params; 
    req = urllib.request.urlopen(str(baseurl)); 
    response = simplejson.load(req); 

而我得到的錯誤是:

Traceback (most recent call last): 
    File "D:\GIS\Arctools\ElevationChart - Copy.py", line 85, in <module> 
    getElevation(pathStr) 
    File "D:\GIS\Arctools\ElevationChart - Copy.py", line 45, in getElevation 
    response = simplejson.load(req); 
    File "C:\Python32\lib\json\__init__.py", line 262, in load 
    parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) 
    File "C:\Python32\lib\json\__init__.py", line 307, in loads 
    return _default_decoder.decode(s) 
    File "C:\Python32\lib\json\decoder.py", line 351, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
TypeError: can't use a string pattern on a bytes-like object 

任何幫助表示讚賞。

回答

6

在Python 3,二進制數據,諸如HTTP請求的原始響應,存儲在字節對象。 json/simplejson需要字符串。解決方案是將字節數據解碼爲字符串數據,並使用適當的編碼,您可以在標題中找到它們。

你找到編碼:

encoding = req.headers.get_content_charset() 

然後通過使內容的字符串:

body = req.readall().decode(encoding) 

這個身體,那麼你可以傳遞給JSON裝載機。

(另外,請停止調用響應「請求」。這是令人困惑,並使其聽起來就像是一個請求,它不是。)

+0

我不明白,我把改變。 – user876307

+0

hi regebro,pl。指導我在下面的代碼,我錯了。 – user876307

+2

@ user876307:沒有「改變」,有幾個必要的。首先你需要弄清楚響應的編碼方式,我會更新答案。此外,撰寫4條評論也沒有意義。一個本來就夠了。 –

11

帖子是有點晚,但最近跑進同樣的問題。下面的解決方案爲我工作。 Lennart基本上說過。

from urllib import request 
import json 

req = request.urlopen('https://someurl.net/api') 
encoding = req.headers.get_content_charset() 
obj = json.loads(req.read().decode(encoding)) 
+1

永遠不會太遲!感謝您的解決方案。 – cdarke

+0

你剛剛救了我! – Wurstbro