文档结构

  • 概念简介
  • 代码引用
    • 代码引入

概念简介

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
    注意,这个表示[start,end],即是包含请求头的start及end字节的,所以,下一个请求,应该是上一个请求的[end+1, nextEnd]

官方类库:

代码引用

类库 requests 作为 HTTP请求库;
当请求时设置steam=True的时候就不会立即关闭连接,此时以流的形式读取body,直到所有信息读取完全或者调用Response.close关闭连接。

代码引入

Response = requests.get(url, stream=True, verify=False)
total_size = int(Response.headers.get('content-length', 0))
# 【1】判断本地文件是否存在,存在则读取文件数据大小
if Path(paths).exists():temp_size = os.path.getsize(paths)
else:temp_size = 0
if temp_size >= total_size:print("下载完成")return paths
# 【2】重新请求网址,加入新的请求头的
header = {"Range": f"bytes={temp_size}-{total_size}"}
Req = requests.get(url,headers=header,stream=True, verify=False)
# 【3】"ab"表示追加形式写入文件
with open(paths, "ab") as file, tqdm(# 【4】tqdm设置参数:initial initial=temp_size,desc="正在下载",total=total_size,unit='',unit_scale=True,unit_divisor=1024,
) as bar:for data in Req.iter_content(chunk_size=1024):  # 边下载边存硬盘size = file.write(data)bar.update(size)
return paths

断点续传需要考虑的功能点:
1、用户自定义性:可以定义cookie、referer、user-agent。如某些下载站检查用户登录才允许下载等情况。
2、很多服务端不支持断点续传,如何判断?
3、怎么去表达进度条?
4、如何得知文件的总大小?使用HEAD请求?那么服务器不支持HEAD请求怎么办?
5、下载后的文件名(header中可能有filename,url中也有filename,用户还可以自己指定filename),怎么处理?还要考虑windows不允许哪些字符做文件名。
6、如何去分块,是否加入多线程。

  • 断点续传代码样例
def download_file(url):local_filename = url.split('/')[-1]# NOTE the stream=True parameterr = requests.get(url, stream=True)with open(local_filename, 'wb') as f:for chunk in r.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunksf.write(chunk)f.flush()return local_filename
  • 优化版实现
#!/usr/bin/python
# encoding=utf-8
import requests, sys, os, re, time
from optparse import OptionParserclass wget:def __init__(self, config = {}):self.config = {'block': int(config['block'] if config.has_key('block') else 1024),}self.total = 0self.size = 0self.filename = ''def touch(self, filename):with open(filename, 'w') as fin:passdef remove_nonchars(self, name):(name, _) = re.subn(ur'[\\\/\:\*\?\"\<\>\|]', '', name)return namedef support_continue(self, url):headers = {'Range': 'bytes=0-4'}try:r = requests.head(url, headers = headers)crange = r.headers['content-range']self.total = int(re.match(ur'^bytes 0-4/(\d+)$', crange).group(1))return Trueexcept:passtry:self.total = int(r.headers['content-length'])except:self.total = 0return Falsedef download(self, url, filename, headers = {}):finished = Falseblock = self.config['block']local_filename = self.remove_nonchars(filename)tmp_filename = local_filename + '.downtmp'size = self.sizetotal = self.totalif self.support_continue(url):  # 支持断点续传try:with open(tmp_filename, 'rb') as fin:self.size = int(fin.read())size = self.size + 1except:self.touch(tmp_filename)finally:headers['Range'] = "bytes=%d-" % (self.size, )else:self.touch(tmp_filename)self.touch(local_filename)r = requests.get(url, stream = True, verify = False, headers = headers)if total > 0:print "[+] Size: %dKB" % (total / 1024)else:print "[+] Size: None"start_t = time.time()with open(local_filename, 'ab+') as f:f.seek(self.size)f.truncate()try:for chunk in r.iter_content(chunk_size = block): if chunk:f.write(chunk)size += len(chunk)f.flush()sys.stdout.write('\b' * 64 + 'Now: %d, Total: %s' % (size, total))sys.stdout.flush()finished = Trueos.remove(tmp_filename)spend = int(time.time() - start_t)speed = int((size - self.size) / 1024 / spend)sys.stdout.write('\nDownload Finished!\nTotal Time: %ss, Download Speed: %sk/s\n' % (spend, speed))sys.stdout.flush()except:# import traceback# print traceback.print_exc()print "\nDownload pause.\n"finally:if not finished:with open(tmp_filename, 'wb') as ftmp:ftmp.write(str(size))if __name__ == '__main__':parser = OptionParser()parser.add_option("-u", "--url", dest="url",  help="target url")parser.add_option("-o", "--output", dest="filename",  help="download file to save")parser.add_option("-a", "--user-agent", dest="useragent", help="request user agent", default='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 \(KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36')parser.add_option("-r", "--referer", dest="referer", help="request referer")parser.add_option("-c", "--cookie", dest="cookie", help="request cookie", default = 'foo=1;')(options, args) = parser.parse_args()if not options.url:print 'Missing url'sys.exit()if not options.filename:options.filename = options.url.split('/')[-1]headers = {'User-Agent': options.useragent,'Referer': options.referer if options.referer else options.url,'Cookie': options.cookie}wget().download(options.url, options.filename)

工具下载方式:https://github.com/phith0n/py-wget
============================================= over ============================================

Python-断点续传相关推荐

  1. python 断点续传

    python 断点续传 1.前序 2.技术原理 2.1 Content-Range 2.2 Range 3. 代码实现 1.前序 当下载突然断开后,断点续传就需要了,继续前面下载的内容下载.解决了不需 ...

  2. python断点续传代码

    具体见链接 https://github.com/orangle/CodeHouse/blob/master/python/flask_upload/chunk_download.py 转载于:htt ...

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

    图片下载 tqdm tqdm是一个快速.扩展性强的进度条工具库,用户只需要封装任意的迭代器 tqdm(iterator),tqdm官方文档. 对于爬虫进度的监控,这是个不错的工具. requests模 ...

  4. python断点续传下载_Python 3 爬虫|第12章:并发下载大文件 支持断点续传

    1. stream 流式下载大文件 1.1 stream=True 和 iter_content() 我们将继续使用 Python 3 爬虫|第3章:同步阻塞下载 所搭建的测试环境,在 Nginx 默 ...

  5. python断点续传下载_python requests 断点续传下载

    1.安装requests: pip install requests 2.实例: # # encoding:utf-8 import requests import os import time de ...

  6. 新技能 get —— Python 断点续传下载文件

    from urllib.request import urlretrieve import sys import osprev_reported_download_percent = None# 首先 ...

  7. 那些ftp服务器支持断点续传,ftp服务器 断点续传

    浅谈FTP服务的几个知识点 实现断点续传的条件有三个:1.FTP服务器要能提供断点续传的功能.目前包括IIS和大部分的FTP架设软件都有了这个功能.2.FTP的登录软件要有断点续传的功能.像Flash ...

  8. python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

  9. python socketserver实现服务器端执行命令 上传文件 断点续传

    1 基于socketserver在服务器端实现执行cmd命令和上传文件(断点续传) 2 3 #server: 4 5 #!/usr/bin/env python 6 # -*- coding:utf- ...

  10. python 断点下载_python多进程断点续传分片下载器

    标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提高下载速度. #! /usr/bin/ ...

最新文章

  1. Spacebuilder在Mono上运行修改备忘
  2. 【JetPack】数据绑定 DataBinding 简介 ( 使用要求 | Gradle 版本 | 定义数据类 | 定义数据绑定布局 | Activity 数据绑定 | 绑定类生成规则 )
  3. Android实训日志:基于外部存储卡的音乐播放器V02
  4. Embedding技术在房产推荐中的应用
  5. Tomcat和Resin有什么区别,工作中你怎么选择?
  6. java解析xml文件四种方式介绍、性能比较和基本使用方法
  7. 格子箱被评选为12家最值得注意的亚洲初创科技公司之一
  8. JavaScript学习笔记 - 提升
  9. rocketmq集群搭建 双主双从
  10. 人人网相册加密密码破解
  11. 【Web动画】SVG 线条动画入门
  12. HTML/CSS/Javascript注册登陆界面全模版(表单验证/验证码生成/敏感词屏蔽/炫酷动画/账号信息储存)
  13. 超级表格企业版,最实用的三个功能
  14. vc使用默认的浏览器打开网页代码
  15. windows如何创建计划任务并在窗口界面隐藏运行
  16. java毕业设计bs架构实习管理系统源码+系统+数据库+lw文档+调试运行
  17. Tableau CA考试lod详细级别专题解析
  18. SpringMVC框架 |自定义类型转换器与日期格式化
  19. Element-ui Popconfirm气泡确认框的确认及取消事件不生效
  20. document.title获取当前网页的标题

热门文章

  1. 电脑爱好者计算机杂志,电脑爱好者杂志
  2. 通常所说微型计算机的奔3,【计算机应用基础】.doc
  3. “问问”,一款改变全民问答方式的知识付费社交APP
  4. qt svg文件的读取和保存
  5. android mp3音量增大,嫌弃安卓音量太小?学会这个技巧,音量扩大双倍
  6. 瞎折腾篇:联想笔记本外扩GTX1060——刷BIOS
  7. docker部署2套jumpserver并且mysql互为主从
  8. 精挑细选【三十首】车载导航专用高清mv视频影音库打包下载
  9. 基于Vue和SpringBoot的论文检测系统的设计与实现
  10. springboot教学系统毕业设计-附源码191733