2011-11-04 100 views
4
import json 
import urllib 
import re 
import binascii 

def asciirepl(match): 
    s = match.group() 
    return binascii.unhexlify(s[2:]) 

query = 'google' 
p = urllib.urlopen('http://www.google.com/dictionary/json?callback=a&q='+query+'&sl=en&tl=en&restrict=pr,de&client=te') 
page = p.read()[2:-10] #As its returned as a function call 

#To replace hex characters with ascii characters 
p = re.compile(r'\\x(\w{2})') 
ascii_string = p.sub(asciirepl, page) 

#Now decoding cleaned json response 
data = json.loads(ascii_string) 

運行它,我得到這個錯誤,ValueError異常解碼JSON

[email protected] /tmp $ python2 define.py                                  
Traceback (most recent call last): 
    File "define.py", line 19, in <module> 
    data = json.loads(ascii_string) 
    File "/usr/lib/python2.7/json/__init__.py", line 326, in loads 
    return _default_decoder.decode(s) 
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode 
    obj, end = self.scan_once(s, idx) 
ValueError: Expecting , delimiter: line 1 column 403 (char 403) 

至於我想,JSON是沒有任何錯誤,因爲我從谷歌的服務器收到它。所有,我做的是刪除十六進制字符。任何幫助將不勝感激。

+0

什麼是線1列403(及其周圍)? –

+0

@TimPietzcker rathe而不是等待迴應,我從代碼隱含的URL下載了json文件,並自己對其進行了檢查。我懷疑Izkata做了類似的事情。 –

+0

確實,我複製了shadyabhi的代碼並自己運行 – Izkata

回答

3

解碼\ X轉義可能會產生「標記,這需要重新逸出,因爲它們出現內‘JSON數據內編碼的字符串’

def asciirepl(match): 
    chr = binascii.unhexlify(match.group()[2:]) 
    return '\\' + chr if chr in ('\\"') else chr 

這仍然不會處理控制字符。所以你可能反而要轉換的\ X逃逸到帶有\ U逃逸,這是在JSON標準由json模塊描述和解析。這具有的附帶好處簡單:)

def asciirepl(match): 
    return '\\u00' + match.group()[2:] 
+1

谷歌人可能不應該首先使用\ x樣式轉義。 –

+0

使用\ u轉義解決了這個問題。謝謝。 –

2

字符403是在 「文本」 的第一個嵌入的引號 - 這是無效的JSON:

{ 
    "type":"url", 
    "text":"<a href="http://www.people-communicating.com/jargon-words.html">http://www.people-communicating.com/jargon-words.html</a>", 
    "language":"en" 
} 

這是由服務器返回 - 注意,沒有嵌入報價:

{ 
    "type":"url", 
    "text":"\\x3ca href\\x3d\\x22http://www.people-communicating.com/jargon-words.html\\x22\\x3ehttp://www.people-communicating.com/jargon-words.html\\x3c/a\\x3e", 
    "language":"en" 
} 

做到這一點的最好方法是先解碼json,然後根據需要去除每個字符串的內容。

編輯:如果那真的是無效的JSON,正如Karl Knechtel在評論中所說的那樣,Google應該被告知他們的API不正確。如果Python的實現對有效的JSON有所限制,應該告訴他們修正它。無論您制定什麼樣的解決方法,如果這個問題得到解決,應該很容易刪除。

+1

不幸的是,這不會像描述的那樣工作; '\ x ##'樣式的'json.loads'扼流圈因爲json標準沒有提及'\ x'序列而轉義。但是,應該可以通過首先將'\ x ##'序列轉換爲'\ u00 ##'序列來工作。 –

+0

我不能想出任何方式來閱讀www.json.org上的信息,這將使其有效JSON。他們可能沒有注意到,因爲Javascript本身確實使用了這樣的轉義。 JSON的許多真實世界的解析器似乎有些鬆懈,儘管不是HTML解析器的範圍;) –