使用requests.get().json()时的ValueErrors、ProtocolErrors和ChunkedEncodingErrors

2024-09-28 05:19:57 发布

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

我正在用Python从比特币区块链收集数据(交易量、采矿费等)。为此,我尝试在blockchain.info上查询各种页面

导入json、请求和urlopen后,我用以下代码开始我的代码:

url = "https://blockchain.info/rawblock/00000000000000000000427c2cbfd8868c5bc987603d2483c9637f052316f89f?"
currentblock = requests.get(url, stream = True).json()
prevhash = str(currentblock['prev_block'])

我选择在最近的块(url中/rawblock/之后的所有内容都是该块的id)上启动代码,然后从requests.get(url, stream=True).json()的输出开始, 我获取链中上一个块的id(然后在下一个循环/周期中查询)

我进入一个for循环,重复从每个块收集信息的过程,获取前一个块的id,然后继续以这种方式向后查询:

prevhash = str(currentblock['prev_block'])
for num in range(0,2700):
    currenthash = prevhash
    url = "https://blockchain.info/rawblock/" + currenthash + "?"
    print(currenthash)
    try:
        currentblock = requests.get(url, stream = True).json()
    except ValueError:
        print(hashnum)
        print("Response content is not JSON")
    prevhash = currentblock['prev_block']

我设置try(序列除外)的原因是,在看似随机的时间间隔内,我会得到一个错误,该错误会停止我的程序,它说来自requests.get()的响应不是JSON。我发现,如果我只是捕捉到这个错误,程序就会再次查询网页,而且大多数情况下,在第二次尝试时,一切正常,程序会继续运行

然而,我只是遇到了一系列看起来很糟糕的错误,老实说,我不知道它们是什么意思,也不知道如何修复它们

以下是回溯(已采取中间步骤):

Traceback (most recent call last):
  File "C:\Users\Vlad\Desktop\lib\site-packages\urllib3\response.py", line 685, in _update_chunk_length
    self.chunk_left = int(line, 16)
ValueError: invalid literal for int() with base 16: b''

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
  File "C:\Users\Vlad\Desktop\lib\site-packages\urllib3\response.py", line 689, in _update_chunk_length
    raise httplib.IncompleteRead(line)
http.client.IncompleteRead: IncompleteRead(0 bytes read)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
  File "C:\Users\Vlad\Desktop\lib\site-packages\urllib3\response.py", line 443, in _error_catcher
    raise ProtocolError("Connection broken: %r" % e, e)
urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  ...
  File "C:\Users\Vlad\Desktop\lib\site-packages\requests\models.py", line 753, in generate
    raise ChunkedEncodingError(e)
requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))

最让我困惑的是,这些错误并不一致(也就是说,如果我尝试完全相同的代码,我不会在与以前相同的时间/地点出现错误)。这是我第一次使用JSON查询,所以我对它一点也不熟悉,但我不知道为什么错误会以看似随机的间隔发生

出于好奇,我在上述错误发生之前,在链中的某个点重新启动了我的程序——这次没有错误。它一直在毫无问题地运行

任何帮助都将不胜感激,如果我能更详细地解释我在做什么,请让我知道

多谢各位


Tags: 代码in程序jsonurlreadgetbytes
1条回答
网友
1楼 · 发布于 2024-09-28 05:19:57

使用重试包重试由于网络错误而失败的请求

import requests
from retry import retry


@retry(exceptions=Exception, tries=5, delay=1)
def get_currentblock(url):
    return requests.get(url)


url = "https://blockchain.info/rawblock/00000000000000000000427c2cbfd8868c5bc987603d2483c9637f052316f89f"
currentblock = get_currentblock(url).json()
prevhash = str(currentblock['prev_block'])
for num in range(0,2700):
    currenthash = prevhash
    url = "https://blockchain.info/rawblock/" + currenthash
    print(currenthash)
    try:
        currentblock = get_currentblock(url).json()
    except ValueError:
        print(hashnum)
        print("Response content is not JSON")
    prevhash = currentblock['prev_block']

这将在任何Exception发生延迟时,以1秒的延迟重试get()最多五次。当您更好地了解可能遇到的异常时,您可能希望将exceptions=Exception更改为更严格的限制。get_currentblock()方法只返回响应而不是JSON组件,以避免触发对JSON解析错误的重试,即我们只希望在发生网络错误时重试

还请注意stream=True已从get()调用中删除,因为它与json()调用一起无效,因为在尝试将内容解析为JSON对象之前必须接收整个响应。流式请求用于在响应内容上获取迭代器,以便在接收到每一行时对其进行处理,但这里并不是这样使用的

最后,我从URL的末尾删除了??表示以下查询参数,但由于没有查询参数,因此不需要

相关问题 更多 >

    热门问题