python断点续传下载_Python版本,图片,视频断点续传下载

图片下载

tqdm

tqdm是一个快速、扩展性强的进度条工具库,用户只需要封装任意的迭代器 tqdm(iterator),tqdm官方文档。

对于爬虫进度的监控,这是个不错的工具。

requests模块实现下载

对于requests的网络请求返回结果中,当需要获取文本的时候我们会使用response.text获取文本信息,使用response.content获取字节流,比如下载图片保存到一个文件,而对于大个的文件我们就要采取分块读取的方式了。

第一步,我们需要设置requests.get的stream参数为True。

默认情况下是stream的值为false,它会立即开始下载文件并存放到内存当中,倘若文件过大就会导致内存不足的情况.当把get函数的stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载。需要注意一点:文件没有下载之前,它也需要保持连接。

断点续传

所谓断点续传,也就是要从文件已经下载的地方开始继续下载。在以前版本的 HTTP 协议是不支持断点的,HTTP/1.1 开始就支持了。一般断点下载时会用到 header请求头的Range字段,这也是现在众多号称多线程下载工具(如 FlashGet、迅雷等)实现多线程下载的核心所在。

HTTP请求头Range

range是请求资源的部分内容(不包括响应头的大小),单位是byte,即字节,从0开始.

如果服务器能够正常响应的话,服务器会返回 206 Partial Content 的状态码及说明.

如果不能处理这种Range的话,就会返回整个资源以及响应状态码为 200 OK .(这个要注意,要分段下载时,要先判断这个)。

Range请求头格式

Range: bytes=start-end

Range头域

Range头域可以请求实体的一个或者多个子范围。例如,

表示头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]

程序实现

这里的断点续传没有做过度复杂的实现,只是简单的在当前目录下进行的。

# -*- coding: utf-8 -*-

import requests

from tqdm import tqdm

import os

import time

# 用法一

def tqdm_demo():

text = ""

for char in tqdm(["a", "b", "c", "d"]):

text = text + char

time.sleep(0.5)

# 用法二

def tqdm_demo2():

pbar = tqdm(["a", "b", "c", "d"])

for char in pbar:

time.sleep(0.5)

pbar.set_description("Processing %s" % char)

# 手动控制运行

# tqdm.update()方法用于手动更新进度条,对读取文件之类的流操作非常有用。

def tqdm_demo3():

with tqdm(total=100) as pbar:

for i in range(10):

pbar.update(10)

time.sleep(0.5)

def download_from_url(url, dst):

'''

:param url: 下载地址

:param dst: 文件名称

:return:

'''

#发起网络请求

response = requests.get(url, stream=True)

#获取返回的文件的大小

file_size = int(response.headers['content-length'])

#判断当前目录中是否有该文件,如果有获取文件的大小,从而实现断点续传

if os.path.exists(dst):

first_byte = os.path.getsize(dst)

else:

first_byte = 0

#如果文件大小已经超过了服务器返回的文件的大小,返回文件长度

if first_byte >= file_size: #(4)

return file_size

#设置断点续传的位置

header = {"Range": f"bytes=%s-%s"%(first_byte,file_size)}

# desc :进度条的前缀

# unit 定义每个迭代的单元。默认为"it",即每个迭代,在下载或解压时,设为"B",代表每个“块”。

# unit_scale 默认为False,如果设置为1或者True,会自动根据国际单位制进行转换 (kilo, mega, etc.) 。比如,在下载进度条的例子中,如果为False,数据大小是按照字节显示,设为True之后转换为Kb、Mb。

#total:总的迭代次数,不设置则只显示统计信息,没有图形化的进度条。设置为len(iterable),会显示黑色方块的图形化进度条。

pbar = tqdm(total=file_size, initial=first_byte,unit='B', unit_scale=True, desc=dst)

#发送网络请求

req = requests.get(url, headers=header, stream=True) #(5)

#这里的二进制需要采用追加的方式写入文件,不然无法实现断点续传

with(open(dst, 'ab')) as f:

for chunk in req.iter_content(chunk_size=1024): #(6)

if chunk:

#用于方便观察进度条,在下载大视频的时候去掉也能观察出来

time.sleep(0.01)

f.write(chunk)

f.flush()

pbar.update(1024)

pbar.close()

return file_size

if __name__ == '__main__':

url = "https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1551406646&di=a385cb186c0f1c2c45e5c49b4015e848&src=http://img18.3lian.com/d/file/201709/21/f498e01633b5b704ebfe0385f52bad20.jpg"

download_from_url(url, "百度美女图片.jpg")

#以下是tqdm实例

tqdm_demo()

tqdm_demo2()

tqdm_demo3()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值