python - python请求随机中断JSONDecodeError
问题描述
我已经调试了好几个小时,为什么我的代码会因为这个错误而随机中断: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"
]
]
}
}
解决方案
查看此 API的文档,似乎唯一的响应是 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 的错误是 a ValueError
,而不是 aJSONDecodeError
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
行更改为包含 aValueError
而不是json.decoder.JSONDecodeError
.
推荐阅读
- android - Android为滞后/慢速按钮设置加载通知
- php - 在woocommerce订单列中单击按钮时如何执行curl命令
- javascript - 带有 for 循环的异步函数等待 http.request
- python - 如何在融合的 kafka 中调试 AvroConsumer?
- r - 在 R 中创建适用于不同类型输入的灵活函数
- java - 如何强制调用handleFault()
- unity3d - Unity中Arcore和arcore android sdk的区别
- arrays - 如何检查模式的字段是字符串数组类型
- c++ - 如何在 CPP 的特定索引中将子字符串插入主字符串?
- assembly - 将较小大小的值移动到寄存器中