API请求期间偶发JSONDECODER错误

2024-06-16 13:21:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个简单的程序,它从Bitstamp.net并使用它。参见下面的代码。在

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分钟后出现偶发的jsondecoderror,有时在几个小时后。我到处都找过了,弄不明白。请参阅下面的错误。非常感谢任何帮助!在

^{pr2}$

Tags: 代码https程序apiurlnetdefwww
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_跟踪()出错。在

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

根据经验,如果你得到了一个错误,但不是一直都有,那就是一个race condition,这是'输出依赖于其他不可控制事件的顺序或时间。当事件没有按程序员所希望的顺序发生时,它就会变成一个bug

所以,我想出了一个解决办法,虽然我不确定这是最优雅的解决办法。Jason认为这是一个超时错误,这是正确的。我更改了以下代码:

r = requests.get(url)

^{pr2}$

通过这种改变,错误基本上消失了。但是,我需要向except子句添加代码,该代码仍将填充此值。为此,我添加了一个单独的请求在定义getBitcoinPrice()之前,它为我提供了这种情况的值。代码如下:

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

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

相关问题 更多 >