2011-11-04 106 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解析器的范围;) –