我正在使用 python 3.5 requests 模块使用以下代码下载文件,如何使此代码“自动恢复”部分下载的文件的下载。
response = requests.get(url, stream=True)
total_size = int(response.headers.get('content-length'))
with open(file_path + file_name, "wb") as file:
for data in tqdm(iterable = response.iter_content(chunk_size = 1024), total = total_size//1024, unit = 'KB'):
file.write(data)
我宁愿只使用 requests
如果可能的话,模块来实现这一点。
最佳答案
我认为 requests
没有内置此功能,但您可以非常轻松地手动完成(只要服务器支持它)。
关键是 Range 请求。要获取从字节 12345 开始的部分资源,请添加以下 header :
Range: bytes=12345-
然后您可以将结果附加到您的文件中。
<小时/>理想情况下,您应该验证是否返回 206 Partial Content
而不是 200
,并且 header 包含您想要的范围:
Content-Range: bytes 12345-123456/123456
Content-Length: 111112
您可能还想预先验证服务器是否处理范围。您可以通过查看初始响应中的 header 或执行 HEAD
来执行此操作,该操作会检查以下内容:
Accept-Ranges: bytes
如果 header 完全丢失,或者没有 none
作为值,或者具有不包含 bytes
的值列表,则服务器不支持正在恢复。
还可以检查Content-Length
以验证您在被中断之前是否尚未完成整个文件。
所以,代码看起来像这样:
def fetch_or_resume(url, filename):
with open(filename, 'ab') as f:
headers = {}
pos = f.tell()
if pos:
headers['Range'] = f'bytes={pos}-'
response = requests.get(url, headers=headers, stream=True)
if pos:
validate_as_you_want_(pos, response)
total_size = int(response.headers.get('content-length'))
for data in tqdm(iterable = response.iter_content(chunk_size = 1024), total = total_size//1024, unit = 'KB'):
f.write(data)
编写下载管理器类型软件的人的一个常见错误是试图跟踪先前请求中已读取的内容。不要这样做,只需使用文件本身来告诉您您有多少。毕竟,如果您读取 23456 字节但仅将 12345 写入文件,那么 12345 就是您想要开始的位置。
关于python - 如何在Python 3.5中恢复文件下载?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51812449/