首页 > 解决方案 > 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并且遇到了以下“特殊”情况:

  1. requests.get(url)返回成功的 200 响应并requests.get(url).text返回 html。我在网上读到使用时应该会失败requests.get(url).json(),因为它无法读取 html,但不知何故它不会中断。为什么是这样?

  2. 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"
      ]
    ]
  }
}

标签: pythonpython-requests

解决方案


查看此 API的文档,似乎唯一的响应是 JSON 格式,因此接收 HTML 很奇怪。要增加接收 JSON 响应的可能性,您可以将“Accept”标头设置为“application/json”。

我尝试使用参数多次查询此 API,但没有遇到JSONDecodeError. 此错误可能是服务器端另一个错误的结果。要处理它,除了你当前的错误except之外,并以与.json.decoder.JSONDecodeErrorConnectionErrorexceptConnectionError

这是一个考虑到所有这些的示例:

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.


推荐阅读