【发布时间】:2014-07-10 07:44:45
【问题描述】:
我正在使用请求从服务器下载文件(数 GB)。为了提供进度更新(并防止整个文件必须存储在内存中),我设置了 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)
但是,在下载的某个随机点,Requests 会抛出一个ChunkedEncodingError。我已经进入源代码并发现this corresponds to an IncompleteRead exception。我在这些行周围插入了一条日志语句,发现e.partial = "\r"。我知道服务器对下载的优先级较低,我怀疑当服务器等待太长时间发送下一个块时会发生此异常。
正如预期的那样,异常会停止下载。不幸的是,服务器没有实现 HTTP/1.1 的内容范围,所以我不能简单地恢复它。我已经尝试增加 urllib3 的内部超时,但异常仍然存在。
有没有办法让底层的 urllib3(或 Requests)更能容忍这些空(或迟到的)块,以便文件可以完全下载?
【问题讨论】:
-
你在哪个平台上?我是否可以建议使用可以通过 shell 调用的专门供您使用的工具,例如 curl?
-
您可以尝试在 get 中设置更长的超时时间吗(kwarg 超时应该在 2.3 中使用 stream=True,请参阅 github.com/kennethreitz/requests/issues/1803)。我还将验证您的内容类型和编码标头是否与您期望的相符,以确保它不会截断流
-
您尝试过使用较小的块吗?好像我一直用 1024 或 2048。
标签: python exception python-requests chunked-encoding