文件在传输中断后,下次传输可以在上次中断的位置继续传输未传输的那部分。
如果碰到网络故障,或者暂停,可以从已经上传或下载的部分开始继续上传或下载未完成的部分,而没有必要从头开始上传下载,用户可以节省时间,提高速度。
range是请求资源的部分内容(不包括响应头的大小),单位是byte,即字节,从0开始。
如果服务器能够正常响应的话,服务器会返回 206 Partial Content 的状态码及说明。
如果不能处理这种Range的话,就会返回整个资源以及响应状态码为 200 OK。
Range: bytes=start-end
ange头域可以请求实体的一个或者多个子范围。例如,
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
例如
Range: bytes=10- :第10个字节及最后个字节的数据
Range: bytes=40-100 :第40个字节到第100个字节之间的数据.
注意,这个表示[start,end],即是包含请求头的start及end字节的,所以,下一个请求,应该是上一个请求的[end+1, nextEnd]
可以发送一个请求头有"Range":"bytes=0-"的head请求,测试一下服务求是否支持断点续传,如果返回状态码是206,并且返回头部header中有Range-content等标志,那就是支持断点续传。
# 同步下载文件加断点续传
import requests
import time
import os
def download(url, filename):
start = time.time()
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0"
}
headers["Range"] = "bytes=0-"
resp = requests.head(url=url, headers=headers)
if resp.status_code == 206:
print(‘服务器支持断点续传...‘)
file_size = int(resp.headers["content-length"])
if os.path.exists(filename):
wrote_byte = os.path.getsize(filename)
print(‘继续下载文件...‘)
else:
wrote_byte = 0
print(‘开始下载文件...‘)
if wrote_byte >= file_size:
return
headers["Range"] = f"bytes={wrote_byte}-"
rep = requests.get(url=url, headers=headers, stream=True)
with open(filename, "ab") as f:
for chunk in rep.iter_content(chunk_size=1024): # (6)
if chunk:
f.write(chunk)
f.flush()
end = time.time() - start
print(f"用了{end}秒,或{end/60}分钟")
else:
print(‘服务器不支持断点续传......‘)
原文:https://www.cnblogs.com/NEGAN-H/p/14615507.html