如何在Python中恢复文件下载?

28
我正在使用 Python 2.7 的 requests 模块下载二进制文件,以下是代码,请问如何使此代码能够从部分下载的文件自动恢复下载。
r = requests.get(self.fileurl, stream=True,  verify=False, allow_redirects=True)
if r.status_code == 200:
    CHUNK_SIZE = 8192
    bytes_read = 0
    with open(FileSave, 'wb') as f:
        itrcount=1
        for chunk in r.iter_content(CHUNK_SIZE):
            itrcount=itrcount+1
            f.write(chunk)
            bytes_read += len(chunk)
            total_per = 100 * float(bytes_read)/float(long(audioSize)+long(videoSize))


            self.progress_updates.emit('%d\n%s' % (total_per, 'Download Progress : ' + self.size_human(itrcount*CHUNK_SIZE) + '/' + Total_Size))
r.close()

如果可能的话,我更喜欢只使用requests模块来实现这个。

1个回答

32

如果Web服务器支持范围请求,则可以在您的请求中添加Range头:

如果Web服务器支持范围请求,则可以在您的请求中添加Range头:

Range: bytes=StartPos-StopPos

您将收到StartPos和StopPos之间的部分。如果不知道StopPos,只需使用:

Range: bytes=StartPos-

那么你的代码将是:

def resume_download(fileurl, resume_byte_pos):
    resume_header = {'Range': 'bytes=%d-' % resume_byte_pos}
    return requests.get(fileurl, headers=resume_header, stream=True,  verify=False, allow_redirects=True)

15
你还需要将文件模式从'wb'更改为'ab'(以追加的方式写入,否则会覆盖已保存的部分)。 - m.kocikowski
作为参考,resume_byte_pos是文件的当前大小还是文件的当前大小减一? - Klik
4
如果您下载了0字节,则不要从-1开始,@Klik肯定不是当前文件大小减一的意思 :) 索引从0开始,因此您应该将当前文件大小作为起始字节发送。 - Piotr Dabkowski
3
比如,您通过Range头请求0-2000000字节。然后,您可以使用“from pathlib import Path; path = Path(..); print(path.stat().st_size)”检查文件大小,并返回2000001个字节。您可以使用这个数字作为Range头的参数来请求2000001字节之后的部分。 - tobiasraabe
1
仅供参考:[1] 如果已经使用ab打开文件,则可以将f.tell()用作resume_byte_pos。 [2] 如果发送了Range: bytes =,则可能会响应不同的标头,请注意(在我的情况下,如果我发送此内容,则会缺少Content-Length,因此我需要解析Content-Range以用于进度条使用的总长度)。 - 林果皞

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接