我已经调试了几个小时,为什么我的代码因以下错误而随机中断:JSONDecodeError: Expecting value: line 1 column 1 (char 0)
这是我的代码:
while True:
try:
submissions = requests.get('http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since).json()['submission']['records']
break
except requests.exceptions.ConnectionError:
time.sleep(100)
我已经通过打印requests.get(url)
和requests.get(url).text
进行调试,并且遇到了以下“特殊”情况:
requests.get(url)
返回成功的200响应,而requests.get(url).text
返回html。我已经在线阅读了使用requests.get(url).json()
时应该失败的信息,因为它无法读取html,但是以某种方式不会损坏。为什么会这样?
requests.get(url)
返回成功的200响应,并且requests.get(url).text
为json格式。我不明白为什么转到requests.get(url).json()
行时会因JSONDecodeError而中断?
情况2的requests.get(url).text
的确切值为:
{
"submission": {
"columns": [
"pk",
"form",
"date",
"ip"
],
"records": [
[
"21197",
"mistico-form-contacto-form",
"2018-09-21 09:04:41",
"186.179.71.106"
]
]
}
}
答案 0 :(得分:1)
看这个API的documentation,似乎唯一的响应是JSON格式,因此接收HTML很奇怪。为了增加接收JSON响应的可能性,可以将“ Accept”标头设置为“ application / json”。
我尝试使用参数多次查询此API,但没有遇到JSONDecodeError
。此错误可能是服务器端另一个错误的结果。要处理此错误,除了您目前except
遇到的json.decoder.JSONDecodeError
错误之外,ConnectionError
和except
并以与ConnectionError
相同的方式处理此错误。>
这是一个考虑了所有内容的示例:
import requests, json, time, random
def get_submission_records(client, since, try_number=1):
url = 'http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since
headers = {'Accept': 'application/json'}
try:
response = requests.get(url, headers=headers).json()
except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError):
time.sleep(2**try_number + random.random()*0.01) #exponential backoff
return get_submission_records(client, since, try_number=try_number+1)
else:
return response['submission']['records']
我也将此逻辑包装在一个递归函数中,而不是使用while
循环,因为我认为它在语义上更加清晰。此函数还会等待,然后再尝试使用指数退避(每次失败后要等待两倍的时间)。
编辑:对于Python 2.7,尝试解析错误的json产生的错误是ValueError
,而不是JSONDecodeError
import requests, time, random
def get_submission_records(client, since, try_number=1):
url = 'http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since
headers = {'Accept': 'application/json'}
try:
response = requests.get(url, headers=headers).json()
except (requests.exceptions.ConnectionError, ValueError):
time.sleep(2**try_number + random.random()*0.01) #exponential backoff
return get_submission_records(client, since, try_number=try_number+1)
else:
return response['submission']['records']
因此只需更改该except
行,使其包含ValueError
而不是json.decoder.JSONDecodeError
。
答案 1 :(得分:-1)
尝试一下。可能有效
while True:
try:
submissions = requests.get('http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since).json()['submission']['records']
sub = json.loads(submissions.text)
print(sub)
break
except requests.exceptions.ConnectionError:
time.sleep(100)