目录
  • 1.前序
  • 2.技术原理
    • 2.1 content-range
    • 2.2 range
  • 3. 代码实现

    1.前序

    当下载突然断开后,断点续传就需要了,继续前面下载的内容下载。解决了不需要重复下载

    2.技术原理

    http/1.1 开始支持断点续传,一般断点下载会用到 range 和 content-range 实体头
    range是请求头,content-range是响应头

    2.1 content-range

    用于响应头中

    语法:

    content-length: <length>

    2.2 range

    rangehttp 请求头表示服务器应返回的文档部分。可以同时用一个头请求多个部件,服务器可以在多部分文档中发回这些范围。如果服务器发回范围,则使用 206 部分内容进行响应。如果范围无效,服务器会返回 416 范围不可满足的错误。服务器还可以忽略标题,然后返回整个文档,并返回 200 状态代码。

    语法:

    range: <unit>=<range-start>-
    range: <unit>=<range-start>-<range-end>
    range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
    range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
    range: <unit>=-<suffix-length>

    unit:指定范围的单位,通常是bytes。
    range-start:指示请求范围开始的给定单元中的整数。
    range-end:给定单元中的整数,指示所请求范围的末尾。此值是可选的,如果省略,文档的末尾将被视为范围的末尾。
    suffix-length:给定单位中的整数,指示要返回的文件末尾的单位数。

    例子:
    (1)从文件中请求三个范围。第一个范围为第200字节到第1000个字节的位置;第二个范围为第2000个字节位置到第6576个字节的位置;第三个范围为第19000字节位置之后的全部

    range: bytes=200-1000, 2000-6576, 19000-

    (2)请求文件的前 500 和最后 500 字节。如果范围重叠,服务器可能会拒绝该请求。

    range: bytes=0-499, -500

    3. 代码实现

    import requests
    import os
    headers = {
        'user-agent': 'mozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/88.0.4324.182 safari/537.36'
    }
    file_path = './video/1.mp4' # 存储地址
    url = 'https://v3-dy-o.zjcdn.com/410b9087e76fe2360e320463f8586ed8/6185ea7a/video/tos/cn/tos-cn-ve-15-alinc2/62427caf076b4d7d9dbbdbea98f97c9f/?a=6383&br=2690&bt=2690&cd=0%7c0%7c0&ch=26&cr=0&cs=0&cv=1&dr=0&ds=3&er=&ft=jal9w1-etz7thwr7wlct&l=021636162458101fdbd400a040000000a70125e00000141b4be97&lr=all&mime_type=video_mp4&net=0&pl=0&qs=0&rc=m3u8bdw6zmzsodmzngkzm0appdy3ozs7mzw7nzy6n2g0awdqngvfcjrnzg5gls1kltbzczu2mv40ly40nmatlv8xlwi6yw%3d%3d&vl=&vr='
    r = requests.get(url,headers=header)
    total_size = int(r.headers['content-length']) # 查看文件大小,并转换为整数类型
    print(r.headers)
    # 查看本地下载了多少
    if os.path.exists(file_path):
        temp_size = os.path.getsize(file_path)  # 本地已经下载的文件大小
    else:
        temp_size = 0
    
    print('已下载:' + temp_size) 
    print('总共需要下载:' + total_size)
    header['range'] = 'bytes={}-'.format(temp_size) # 向头加入range信息
    print(header) # 打印头信息
    r = requests.get(url, headers=header, stream=true)
    with open(file_path, "ab") as f:
            for chunk in r.iter_content(chunk_size=1024):
                if chunk:
                    temp_size += len(chunk)
                    f.write(chunk)
                    
    

    现在不知到怎么做突然下载被停止后,数据能写入文件了,所以现在是手动模拟下载断开。

    在写入文件中加入了一个判断,当文件下载了5m时停止下载,之后再删掉这段代码,在重新下载。

    with open(file_path, "ab") as f:
            for chunk in r.iter_content(chunk_size=1024):
                if chunk:
                    temp_size += len(chunk)
                    f.write(chunk)
                    if temp_size > 1024 *1024 * 5:
                        break
    

    第一次下载

    第二次下载

    到此这篇关于python 文件下载之断点续传的实现的文章就介绍到这了,更多相关python 断点续传内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!