【问题标题】:Sporadic JSONDecodeError during API RequestAPI请求期间的零星JSONDecodeError
【发布时间】:2017-09-30 09:40:37
【问题描述】:

我正在创建一个简单的程序,它从 Bitstamp.net API 获取“最后一个”值并使用它。请参阅下面的代码。

def getBitcoinPrice():

    url = 'https://www.bitstamp.net/api/ticker/'
    try:
        r = requests.get(url)
        priceFloat = float(json.loads(r.text)['last'])
        return priceFloat
    except requests.ConnectionError:
        print("Error querying Bitstamp API")
        os.system('say "The program broke."')

有时我会在 3 分钟后收到零星的 JSONDecodeError,有时会在几个小时后收到。我到处看了看,无法弄清楚。请参阅下面的错误。非常感谢任何帮助!

File "/Users/paulkaraffa/PycharmProjects/socialbitanalytics/actionEvaluator.py", line 70, in <module>
    btcValues.append(getBitcoinPrice())

File "/Users/paulkaraffa/PycharmProjects/socialbitanalytics/actionEvaluator.py", line 26, in getBitcoinPrice
    priceFloat = float(json.loads(r.text)['last'])

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

【问题讨论】:

    标签: python json api


    【解决方案1】:

    所以,我想出了一个修复方法,尽管我不确定它是否是最优雅的修复方法。 Jason 是正确的,这是一个超时错误。我更改了以下代码:

    r = requests.get(url)
    

    r = requests.get(url, timeout=120.0)
    

    通过进行此更改,错误几乎消失了。但是,我需要将代码添加到仍会填充此值的 except 子句。为此,我在定义 getBitcoinPrice() 之前添加了一个单独的 request.get,它为这种情况提供了一个值。代码如下所示:

    urlException = 'https://www.bitstamp.net/api/ticker/'
    r = requests.get(urlException, timeout=600.0)
    exceptionValue = float(json.loads(r.text)['last'])
    print(exceptionValue)
    
    def getBitcoinPrice():
        url = 'https://www.bitstamp.net/api/ticker/'
        try:
            r = requests.get(url, timeout=120.0)
            priceFloat = float(json.loads(r.text)['last'])
            return priceFloat
    
        except requests.ConnectionError:
            print("Error querying Bitstamp API")
            return exceptionValue
    

    如果有人有更优雅的解决方案,请告诉我! :)

    【讨论】:

    • 查看我的原始答案,我已根据我的建议对其进行了更新。
    【解决方案2】:

    更新:建议解决方案

    def getBitcoinPrice():
    
        url = 'https://www.bitstamp.net/api/ticker/'
        try:
            r = requests.get(url, timeout=60)
            priceFloat = float(json.loads(r.text)['last'])
            return priceFloat
        except json.decoder.JSONDecodeError:
            # wait 5 seconds and try again. This would require you to put your try block 
            # into it's own function so you can more easily call it here in the exception.
        else:
            print("Error querying Bitstamp API")
            os.system('say "The program broke."')
    

    原答案

    当你说你在 3 分钟或几个小时后得到错误时,你的意思是代码运行,等待 3 分钟或几个小时,然后抛出错误?这听起来像是一个超时问题,这意味着如果 URL 在 X 秒内没有响应,它将返回 504 错误,尽管我希望它是一致的 60 秒或 180 秒。我建议使用 Postman 发出请求并查看错误响应。或者更好的是打印当前代码中的错误,或者在错误时输入 pdb.set_trace() 。

    您收到的错误是因为requests.get(url) 失败,这意味着r.textNone,这会导致您的priceFloat 行出错。换句话说,堆栈跟踪中的最后一行 raise JSONDecodeError("Expecting value", s, err.value) from None... 表示 json.loads() 正在传递 None 而不是一个值。

    根据经验,如果您收到错误但并非总是出现错误,则为race condition,即“输出取决于其他不可控事件的顺序或时间”。当事件没有按照程序员预期的顺序发生时,它就变成了一个错误。'

    【讨论】:

    • 感谢您的信息。代码从 API 中获取当前值,然后将其存储在列表变量中。它每 5 秒执行一次。该程序将每 5 秒运行一次获取新值并添加它们,但有时它会因此错误而崩溃。因此,这似乎不是超时问题。我在想这可能是网站的问题,但每次我检查股票时,这些值都显示得很好。
    • 在您的except 子句中,打印r 的值以及您从API 获得的响应。响应将是 400 或更高的 HTML 代码(400 是客户端错误,500 是服务器错误),很可能。您还可以使用 Selenium 获取错误截图。请参阅this SO Question 了解更多信息。
    • 好建议。我会不时这样做,然后看看我运行它时会得到什么。
    • Jason,我尝试了一个 except 子句并在它运行时得到了 。这也是我收到的最后一个 HTML 代码。所以当它坏掉时,一切似乎都在工作。
    • 当您获得JSONDecodeError 时,r 的值是多少?
    猜你喜欢
    • 2021-03-31
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 2019-05-26
    • 2018-10-07
    • 1970-01-01
    • 2020-04-19
    • 2019-08-11
    相关资源
    最近更新 更多