处理返回为空时的 JSON 解码错误

126 投票
2 回答
371514 浏览
提问于 2025-04-17 07:42

我正在解析json数据。解析的过程没有问题,我使用的是simplejson模块。但是,有些API请求返回的是空值。下面是我的一个例子:

{
"all" : {
    "count" : 0,
    "questions" : [     ]
    }
}

这是我解析json对象的代码片段:

 qByUser = byUsrUrlObj.read()
 qUserData = json.loads(qByUser).decode('utf-8')
 questionSubjs = qUserData["all"]["questions"]

正如我提到的,对于某些请求,我遇到了以下错误:

Traceback (most recent call last):
  File "YahooQueryData.py", line 164, in <module>
    qUserData = json.loads(qByUser)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/__init__.py", line 385, in loads
    return _default_decoder.decode(s)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/decoder.py", line 402, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/simplejson/decoder.py", line 420, in raw_decode
    raise JSONDecodeError("No JSON object could be decoded", s, idx)
simplejson.decoder.JSONDecodeError: No JSON object could be decoded: line 1 column 0 (char 0)

处理这个错误的最佳方法是什么呢?

2 个回答

45

如果你不介意引入 json 这个模块,那么处理 JSON 错误的最好方法是使用 json.JSONDecodeError(或者 json.decoder.JSONDecodeError,它们是一样的)。因为如果你用默认的错误类型,比如 ValueError,可能会把其他不相关的错误也捕捉到,这样就不太准确了。

from json.decoder import JSONDecodeError


try:
    qByUser = byUsrUrlObj.read()
    qUserData = json.loads(qByUser).decode('utf-8')
    questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
    # do whatever you want

//编辑(2020年10月):

正如 @Jacob Lee 在评论中提到的,当 JSON 对象不是 strbytesbytearray 时,可能会出现基本的 TypeError 错误。你的问题是关于 JSONDecodeError 的,但这里提一下也是有意义的;为了处理这种情况并区分不同的问题,可以使用以下方法:

from json.decoder import JSONDecodeError


try:
    qByUser = byUsrUrlObj.read()
    qUserData = json.loads(qByUser).decode('utf-8')
    questionSubjs = qUserData["all"]["questions"]
except JSONDecodeError as e:
    # do whatever you want
except TypeError as e:
    # do whatever you want in this case
229

在Python编程中,有一个规则叫做“请求宽恕比请求许可更容易”(简称:EAFP)。这句话的意思是,你应该捕捉错误,而不是事先检查值是否有效。

所以,可以尝试下面的做法:

try:
    qByUser = byUsrUrlObj.read()
    qUserData = json.loads(qByUser).decode('utf-8')
    questionSubjs = qUserData["all"]["questions"]
except ValueError:  # includes simplejson.decoder.JSONDecodeError
    print('Decoding JSON has failed')

编辑:因为 simplejson.decoder.JSONDecodeError 实际上是从 ValueError 继承来的(这里有证据),所以我把捕捉错误的语句简化成只用 ValueError

撰写回答