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

标签 python python-3.x python-requests python-3.6 python-3.5

我正在使用 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/

相关文章:

python - 将字典内的列表值拆分为单独的字典

python - 在两个列表之间有效地找到 "duplicates",其中字典元素只比较字典字段的一个子集

python - 将 Blogger XML 文件转换为 Wordpress WXR - 创建 Python 转换脚本

windows - 为什么我的 Python 多处理工作进程不使用多核?

python - 即使列中不存在数据,Pandas 也会使用自定义列进行数据透视

python - 访问 https 站点 python (urllib2, requests)

python - 尝试获取公会角色时出现 Discord API 401 未经授权错误

python - 使用用户代理 header 时 Webscraping CrunchBase 访问被拒绝

python - 在 WxPython GUI 线程上运行函数

python - 杀死 less(1) 子进程后输入失败