【问题标题】:Python ValueError: No JSON Object Could Be Decoded (Intermittent)Python ValueError:无法解码 JSON 对象(间歇性)
【发布时间】:2018-04-27 21:01:52
【问题描述】:

以下代码出错。但是,有时它有效,有时则无效。我已经用 JSONLint 验证了数据。我尝试根据对类似错误问题的响应对数据进行解码/编码,并使用编解码器模块进行了相同的尝试。我不明白为什么它有时工作正常,然后有时会抛出错误。

import requests
import json
import codecs

response = requests.get("https://api.weather.gov/alerts/active")
print(response.status_code)

with open ('data.json', 'w') as file:
    file.write(response.content)

myFile = open('data.json', 'r')
myObject = myFile.read()
u = myObject.decode('utf-8-sig')
myObject = u.encode('utf-8')
myFile.encoding
myFile.close()
myData = json.loads(myObject, 'utf-8') 

#myData=json.loads(codecs.open(myObject,'r', 'utf-8'))

可以在我提出的另一个问题 here 中找到 JSON 数据的示例。

【问题讨论】:

  • 您尝试加载的 JSON 对象可能存在一些差异。我遇到的一个常见错误是存在一个在一种语言(如 java)中有效的值,而不是在 python 中有效的值。这方面的一个例子是{"Key": null} 这在java 中是有效的JSON,但在python 中不是,因为null 不是python 定义的。我建议在 try/except ValueError 语句中包含 json.loads 语句。然后在 except 块中,打印/写出您传递的字符串,并尝试确定未正确解析的内容。
  • @Matt No. json.loads('{"Key": null}') 将在 Python 中返回 {'Key': None}。所有有效的 JSON 都适用于所有语言的所有符合标准的 JSON 解析器。
  • @abarnert,是的,你是对的,看来我在考虑 ast.literal_eval()
  • @Matt 是的,这只是在 JSON 上不使用 literal_eval 而不是 json.loads 的众多原因之一。

标签: python json python-requests python-2.6


【解决方案1】:

问题是你的 JSON 实际上是无效的。

your other question 中的示例为例,您可以将其粘贴到像this one 这样的JSON 验证器中,然后查看问题:在第35 行,数组中的最后一个值后面有一个逗号。那不是legal JSON。所以没有符合标准的 JSON 解析器会解析它。

这与字符编码无关。因此,添加一堆额外的encodedecode 调用并拉入额外的库来做更多次不会有帮助。您已将字节正确解码为文本,但该文本不是有效的 JSON。


为什么有时会发生,有时却不会?大概(仅基于端点的名称)API 正在从其后端的各个位置收集警报,有时其中一个警报的编码不正确,但大多数时候它们都很好(或者没有任何)。谁知道?这不是你要修复的错误;这是他们的。

事实上,你应该做的第一件事就是向提供者提交一个错误,向他们展示你得到的错误 JSON,并准确指出它有什么问题。 (如果您与他们签订了某种支持合同,您可能想请他们做点什么,这样您就不必解决他们的问题,但我认为您不需要。)


在此期间你能做什么?好吧,如果您可以 try/except JSONDecodeError: 并跳过偶尔出现的错误值,那么在他们解决问题之前,这可能是最好的答案。但是,如果数据不完整会使您的整个程序无效,那就不好了。特别是,在这种情况下,这可能意味着您在某个重要警报出现的整个过程中都没有获得任何数据,因此您永远看不到它。

您可以尝试使用“草率的 JSON”解码器。这通常是一个坏主意,因为很容易以错误的方式默默地解码错误,并将垃圾数据放入您的集合中。这也意味着一旦作者认为这是一个坏主意,大多数此类项目都会被放弃。但是人们一直在写新的,所以如果你真的想,你可以搜索并找到一个。

如果它们的 JSON 中的错误是一致的,并且您可以弄清楚如何描述它们,那么您应该能够编写一个专用的“草率 JSON”解码器来准确处理这些错误,或在解码之前修复这些错误的预处理器。这将是不平凡的,可能有点丑陋,但也许它应该是丑陋的——每次你阅读它时,它都会提醒你检查提供者是否修复了他们的错误,这样你就可以扔掉那个丑陋的代码。无论如何,没有人能够确定他们的错误是否一致,然后编写处理它们的代码,而不仅仅是一个示例。无论如何,可能没有人愿意为你处理一大堆无效的 JSON。因此,如果您想这样做,您将不得不自己尝试这样做(当然,如果您遇到困难,您可以随时提出一个新问题,其中包含所有相关细节)。

【讨论】:

    【解决方案2】:

    你为什么要让代码如此复杂?你可以这样做:

    obj = requests.get("https://api.weather.gov/alerts/active").json()
    

    json 对象会自动为您解码为 pythonic dict。它似乎与 python 2.7.143.6.5 一致。

    【讨论】:

    • 他的 JSON 无效,所以 response.json 不会比 json.loads 更好。
    • 我不知道,我已经用这个 url 运行了这个代码 10 次,它运行得很好......
    • 点击他发布的其他问题的链接。那是无效的 JSON。如果不是这样,他现有的代码就可以正常工作(尽管过于复杂),所以他一开始就不会问这个问题。此外,您怀疑如果服务间歇性地生成错误的 JSON,那么它恰好在几分钟内连续 10 次生成好的 JSON(当时可能没有任何新的或过期的警报)并没有真正证明什么。
    猜你喜欢
    • 2023-03-12
    • 2015-01-04
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    相关资源
    最近更新 更多