本次文章主要是記錄使用python中的requests庫進行如何下載大文件學習記錄。
1.首先請求服務器要下載的文件爲多大及服務器是否支持斷點續傳功能。
2.服務器返回被請求文件大小及斷點續傳功能支持與否的信息。
3.客戶端首先將部分請求的數據寫入文件中,請求頭部可如下:
header={
'Range': 'bytes=0-10'#即要請求的數據位0-10範圍,可以這麼理解即:百分之0 到百分之10 ,每次請求多少由自己定義
}
4.客戶端讀取本地寫入的文件大小,再次請求服務器,再追加到文件中,注意是“再請求”“二進制追加”,且連接可不斷開,部分代碼如下:
header={
'Range': 'bytes=x-x+10'#即要請求的數據位x-x+10範圍,可以這麼理解即:百分之x 到百分之x+10
}
# w:以寫方式打開
# a:以追加模式打開
# r+:以讀寫模式打開
#
# w+:以讀寫模式打卡
#
# rb:以二進制讀模式打開
# wb:以二進制寫模式打開
#
# ab:以二進制追加模式打開
#
# rb+:以二進制讀寫模式打開
# wb+:以二進制讀寫模式打開
open對象常用的方法
read():讀取字節到字符串中
readline():打開文件的一行,包括行結束符
readline():打開文件,讀取所有行
write():將字符串寫入文件,寫入對象爲字符串
writelines():將列表寫入文件,對象是列表。
seek():偏移量
tell():返回當前文件指針的位置
#追加文件
with open("test.docx","wb+") as fn:
fn.write(res.content)
HTTP斷點續傳
實現斷點續傳功能,客戶端要記錄下載進度即下載區域,再續傳就要傳遞下載的區域片段。
HTTP1.1協議(RFC2616)中定義了斷點續傳相關的HTTP頭 Range和Content-Range字段
Ranges用法:
Ranges: (unit=first byte pos)-[last byte pos]
Ranges: bytes=4000- 下載從第4000字節開始到文件結束部分
Ranges: bytes=0~N 下載第0-N字節範圍的內容
Ranges: bytes=M-N 下載第M-N字節範圍的內容
Ranges: bytes=-N 下載最後N字節內容
requests庫中的head
- 以很少網絡流量獲得概要信息
# -*- coding: utf-8 -*-
#本次示例爲http,若要使用https則需要進行SSL部分代理處理,處理方式在其它文章中有提到
import requests
url="http://172.7.1.60"
head=requests.head(url)
print head.headers
'''
打印的信息
{'Content-Length': '481', 'Keep-Alive': 'timeout=10, max=99', 'Server': 'webserver', 'Last-Modified': 'Thu, 01 Mar 2018 06:11:39 GMT', 'Connection': 'keep-alive', 'ETag': '"acc-1e1-5a97999b"', 'Date': 'Fri, 17 Jan 2020 10:59:55 GMT', 'Content-Type': 'text/html'}
'''
# -*- coding: utf-8 -*-
#此腳本只是代碼思路,還有很多要優化的地方
#本次示例爲http,若要使用https則需要進行SSL部分代理處理,處理方式在其它文章中有提到
import requests, sys, os, re, time
import os
url="http://172.7.1.61:80/test/xxx.docx"
url_="http://172.7.1.61:80"
headers={
'Range': 'bytes=0-10'
}
head=requests.head(url,headers=headers)
#查看是否支持 斷點續傳
header_accept=head.headers['Accept-Ranges']
if header_accept=="bytes":
#支持斷點續傳
try:
#功能實現:每10個bytes請求 ,請求
headers={
'Range': 'bytes=0-10'
}
#獲取文件的bytes大小
header_content=head.headers['Content-Range']
print header_content
#提取請求中的文件大小
sd=header_content.split("/")
content=sd[1]
print content
#第一次獲取到10bytes
res=requests.get(url, stream = True, verify = False, headers = headers)
i=10
with open("test.docx","wb+") as fn:
fn.write(res.content)
while i<=int(content):
#每次請求部分資源 以二進制的形式寫入文件中
i=i+10
headers={
'Range': 'bytes='+str(i-10)+"-"+str(i)
}
res=requests.get(url, verify = False, headers = headers)
with open("test.docx","wb+") as fn:
fn.write(res.content)
# pass
except Exception as e:
print e.message
else:
pass
finally:
pass
else:
print ""
# #不支持斷點續傳
# #-------------
# #查看資源的大小及 請求的大小在資源內的範圍
# header_content=head.headers['Content-Range']
# #查看文件更新的變化,可以用來判斷文件是否更新
# header_ETag=head.headers['ETag']
# #HTTP連接,查看HTTP連接狀態
# header_Connection=head.headers['Connection']
# print header_accept,header_content,header_ETag,header_Connection
Requests庫下載大文件腳本
•當流下載時,用Response.iter_content或許更方便些。requests.get(url)默認是下載在內存中的,下載完成才存到硬盤上,可以用Response.iter_content 來邊下載邊存硬盤
#! -*-coding:UTF-8-*-
import os
import requests
#使用requests庫 屏蔽HTTPS錯誤
from requests.packages import urllib3
urllib3.disable_warnings()
#res=requests.get("https://pro.hik-connect.com/download/RemoteWebControl.exe","verify=False",stream=True)
#f=open("asdads.exe","wb")
# name = url_video[url_video.rindex('=') + 1:]
# response = requests.get(url=url_video,headers=headers)
import subprocess
r = requests.get("https://psssss/RemoteWebControl.exe","verify=False", stream=True)
f = open(r"asd.exe", "wb")
print 'xxx'
#迭代讀取內容 讀取的大小爲512bytes
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
else:
break;
pro=subprocess.Popen("E:\\asd.exe", shell=True)
print pro