python 请求随机中断 JSONDecodeError

标签 python python-requests

我已经调试了几个小时,为什么我的代码随机中断并出现此错误: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"
      ]
    ]
  }
}

最佳答案

查看 documentation对于这个 API,似乎唯一的响应是 JSON 格式,所以接收 HTML 很奇怪。要增加接收 JSON 响应的可能性,您可以将“接受” header 设置为“应用程序/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

关于python 请求随机中断 JSONDecodeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52488117/

相关文章:

python - 如何避免在Python中嵌套“for循环”?

python - 语法错误: invalid syntax?

python - sklearn.metrics.precision_recall_curve : Why are the precision and recall returned arrays instead of single values

python - 用于移植到 Python 代码的 Tcl 面向对象扩展

python - 如何从 HTTP header 响应中解析 Content-Type 的值?

python - 如何在 Python 中加载网站的所有资源,包括 AJAX 请求等?

python - 由于 UnicodeDecodeError,解压下载的 .gz 文件失败

python - Flask - 在请求之间将值存储在内存中

Python读取特定的单元格值

python - 请求.exceptions.SSLError : [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl. c:590)