代码执行抛出异常:JSONDecodeError: Expecting value: line 1 column 1 (char 0)
代码中使用了 json.loads
来将 JSON 数据解析成 Python 数据类型:
import json
...many codes...
data = json.loads(resp.text)
但是因为传递给 json.loads
的参数不符合 JSON 格式,所以抛出异常。
不符合 JSON 格式的原因常见的有:
以下是 duplicate 演示:
对应上面常见原因的第一点:
关于 text == """{"foo": 'egg'}"""
这样的格式错误问题,假设 text 是来自REST API 的请求响应,那么原则上来讲应该是服务器软件的问题。所以这里不再多言。如果是自己编写 json 数据字符串错误,则自己修改回来即可。
对应上面常见原因的第二点:
另外一种便是通过 REST API GET 或 POST 等等到的 text
,因为可能存在失败的情况,而有的失败的 response 是普通的 HTML 格式。所以不能不做区分地 .loads
。
这里是一处我原先错误的写法:
import json
import requests
from requests.exceptions import HTTPError
...codes...
def foo():
try:
r = requests.get(url, headers=headers)
print("[debug] json.loads(r.text): ", json.loads(r.text))
r.raise_for_status()
except HTTPError as err:
raise
return json.loads(r.text)
这样就会造成 JSONDecodeError 的错误先于 HTTP 失败的 raise status 发生。
虽然目的是“不管失败还是成功,都打印响应消息”,但是没有意识到这个响应消息格式只有成功的时候才是 JSON 格式。
可以简单的将出现错误的 line 10 修改为:
print("[debug] response content: ", r.text)
或者对成功或失败的 debug 输出做一下区分:
def foo():
try:
r = requests.get(url, headers=headers)
r.raise_for_status()
except HTTPError as err:
print("[error] ({}): {}".format(r.status_code, r.text))
raise
else:
print("[debug] json.loads(r.text): ", json.loads(r.text))
return json.loads(r.text)
如:
{
"foo": "bar",
"egg": "spam",
}
这样的字符串用 json.loads
也是会抛出 JSONDecodeError 的:
...
JSONDecodeError: Expecting property name enclosed in double quotes: line 5 column 1 (char 40)
正确的写法是:
{
"foo": "bar",
"egg": "spam"
}
这也是 JSON 的格式问题。如果字符串是错误的 JSON 语法格式,那么调用 json.loads
来 decode 就会抛出异常。
n/a