针对具有请求2.3.0的空块避免ChunkedEncodingError

Bai*_*ker 11 python exception chunked-encoding python-requests

我正在使用请求从服务器下载文件(几千兆字节).要提供进度更新(并防止整个文件必须存储在内存中),我已将stream=True下载设置并写入文件:

with open('output', 'w') as f:
    response = requests.get(url, stream=True)

    if not response.ok:
        print 'There was an error'
        exit()

    for block in response.iter_content(1024 * 100):
        f.write(block)
        completed_bytes += len(block)
        write_progress(completed_bytes, total_bytes)
Run Code Online (Sandbox Code Playgroud)

但是,在下载中的某个随机点,请求会抛出一个ChunkedEncodingError.我已经进入源代码,发现这对应于IncompleteRead异常.我在这些行周围插入了一条日志语句并发现了e.partial = "\r".我知道服务器给下载的优先级低,我怀疑当服务器等待太长时间发送下一个块时会发生这种异常.

正如预期的那样,例外会停止下载.不幸的是,服务器没有实现HTTP/1.1的内容范围,所以我不能简单地恢复它.我已经玩过增加urllib3的内部超时,但异常仍然存在.

反正有没有让底层urllib3(或请求)更容忍这些空(或晚)块,以便文件可以完全下载?

gus*_*ong 1

import httplib

def patch_http_response_read(func):
    def inner(*args):
        try:
            return func(*args)
        except httplib.IncompleteRead, e:
            return e.partial
    return inner

httplib.HTTPResponse.read = patch_http_response_read(httplib.HTTPResponse.read)
Run Code Online (Sandbox Code Playgroud)

我现在无法重现您的问题,但我认为这可能是一个补丁。它允许您处理有缺陷的 http 服务器。

大多数不良服务器都会传输所有数据,但由于实现错误,它们会错误地关闭会话,并且 httplib 会引发错误并埋葬您宝贵的字节。