【问题标题】:Python request JSON intermittent Type ErrorPython 请求 JSON 间歇性类型错误
【发布时间】:2019-03-21 14:07:37
【问题描述】:

我在 Jupyter Notebooks 中使用 Python (3.5) 向 API 发出大量请求。 代码如下所示:

...
r = requests.post(url=url, json=json, headers=headers)
bar = r.json()["foo"]["bar"]
...

我遇到的问题是它在大多数情况下都能正常工作,但似乎在上面的第二行随机抛出类型错误:“字符串索引必须是整数”。 有人可能会推断这意味着返回的值是一个简单的字符串/不是 JSON 对象,因此不能用键访问,但事实并非如此:如果我用完全相同的请求重新启动(相同的 url,相同的 JSON 查询,相同header),不会抛出错误!

这似乎是随机发生的:有时它可以连续处理数千个请求,有时它会在几百个请求之后发生。 知道为什么会发生这种情况吗?我一直在寻找答案,但没有找到相关的答案。

注意:我意识到我没有提供可重现的示例,但我不能。 我什至无法自己重现该问题,因为它是间歇性发生的。

【问题讨论】:

  • 为什么不包含一个 try-except 块来保存/打印错误的 JSON 对象?
  • 相同的请求并不意味着相同的答案。您应该编写记录返回的未处理内容的代码(至少在发生错误的情况下)。
  • 也许有些请求没有返回您认为的那样,请考虑保存这些错误响应对象之一,并观察它与您想要的响应之间的区别
  • @all:是的,我应该这样做。不知道为什么我没有考虑过。我确实有一个 try-except,但它会重试请求而不是打印出错误的 JSON 对象。

标签: python json python-3.x python-requests


【解决方案1】:

您可以添加一些错误检查以找出返回的数据未按预期格式化的原因:

r = requests.post(url=url, json=json, headers=headers)
try:
    data = r.json()
    foo = data["foo"]
except json.decoder.JSONDecodeError:
    print('response was not a JSON string, but', r.text) 
except KeyError:
    print('data does not contain "foo", but', data)
else:
    try:
        bar = foo["bar"]
    except KeyError:
        print('foo does not contain "bar", but', foo)
    except TypeError:
        print('foo is not a dictionary, but', foo)

【讨论】:

    【解决方案2】:

    这并不一定意味着 r.json() 不是有效的 JSON。它可以是如下所示的 JSON:

    {
      "foo": "randomstring"
    }
    

    运行r.json()["foo"]["bar"] 时会抛出异常,因为r.json()["foo"] 实际上是一个字符串,您需要一个整数来访问其中一个元素。如果它是任何除了字典的东西,你几乎会得到一个例外。

    对此的快速“修复”是将r.json()["foo"]["bar"] 重写为r.json().get("foo", {}).get("bar", None)。这样,如果 JSON 没有“foo”或“foo”字典没有“bar”,则返回的值将是 None,而不是 Exception。

    【讨论】:

    • 不是一个列表,一个字符串,因为错误说“String Indices must be Integers”。所以它看起来像{"foo": "baz"}
    • 这并不能回答问题,因为这不会帮助 OP 确定问题所在,而只是忽略错误
    • 我知道这并不能帮助他找出解决方案,但我希望它能提供一个解决可能导致问题的方法。由 OP 进行进一步调查,imo。
    • 我知道可能是这种情况,但在这种情况下,相同的请求可能总是返回一个包含字符串而不是字典的 JSON 对象。 (除非查询的项目被删除/修改 - 但不是这里的情况,我检查了)
    • 大多数服务对成功和失败的场景有不同的响应。会是这样吗?
    猜你喜欢
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 2012-12-14
    • 2015-07-05
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多