標籤:Python requests 進度條
話不多說,先
該Python代碼可以實現擷取下載的檔案名稱,下載檔案的大小,下載速度等。
代碼關鍵點:
1、關於下載檔案名稱的擷取:代碼裡使用兩種方式擷取:
(1) 通過Content-Disposition屬性,該屬性是作為對下載檔案的一個識別欄位,儲存著下載檔案名稱
(2) 直接通過連結擷取,例如:sw.bos.baidu.com/sw-search-sp/software/8b23f8846df3d/BaiduMusicSetup.exe 檔案後面直接就是檔案名稱了。
2、關於下載檔案大小的擷取:直接從HTTP的響應資訊中擷取,在Content-Length中
3、requests.get(url)預設是下載在記憶體中的,下載完成才存到硬碟上,這樣就無法擷取當前下載進度了,所以要設定邊下邊存硬碟
def downfile(self,filename): #下載檔案 self.r = requests.get(self.url,stream=True) with open(filename, "wb") as code: for chunk in self.r.iter_content(chunk_size=1024): #邊下載邊存硬碟 if chunk: code.write(chunk)
附上Python代碼:
import threadingimport osimport requestsimport timeimport reimport urllibdef view_bar(num, total): #顯示進度條 rate = num/total rate_num = int(rate * 100) number=int(50*rate) r = ‘\r[%s%s]%d%%‘ % ("#"*number, " "*(50-number), rate_num, ) print("\r {}".format(r),end=" ") #\r回到行的開頭class Getfile(): #下載檔案 def __init__(self,url): self.url=url #self.filename=filename self.re=requests.head(url,allow_redirects=True) #運行head方法時重新導向 def getsize(self): try: self.file_total=int(self.re.headers[‘Content-Length‘]) #擷取下載檔案大小 return self.file_total except: print(‘無法擷取下載檔案大小‘) exit() def getfilename(self): #擷取預設下載檔案名稱 filename=‘‘ if ‘Content-Disposition‘ in self.re.headers: n=self.re.headers.get(‘Content-Disposition‘).split(‘name=‘)[1] filename=urllib.parse.unquote(n,encoding=‘utf8‘) elif os.path.splitext(self.re.url)[1]!=‘‘: filename=os.path.basename(self.re.url) return filename def downfile(self,filename): #下載檔案 self.r = requests.get(self.url,stream=True) with open(filename, "wb") as code: for chunk in self.r.iter_content(chunk_size=1024): #邊下載邊存硬碟 if chunk: code.write(chunk) time.sleep(1) #print ("\n下載完成") def downprogress(self,filename): self.filename=filename self.file_size=0 self.file_total=self.getsize() while self.file_size<self.file_total: #擷取當前下載進度 time.sleep(1) if os.path.exists(self.filename): self.down_rate=(os.path.getsize(self.filename)-self.file_size)/1024/1024 self.down_time=(self.file_total-self.file_size)/1024/1024/self.down_rate print (" "+str(‘%.2f‘ %self.down_rate+"MB/s"),end="") self.file_size=os.path.getsize(self.filename) print (" "+str(int(self.down_time))+"s",end="") print (" "+str(‘%.2f‘ %(self.file_size/1024/1024))+"MB",end="") view_bar(self.file_size, self.file_total)if __name__ == ‘__main__‘: url = input("輸入網址:") while not re.match(‘^(https?|ftp)://.+$‘,url): url = input("網址格式錯誤,請重新輸入:") file1=Getfile(url) file_total=file1.getsize() filename=file1.getfilename() if filename==‘‘: filename=input(‘無法擷取下載檔案名稱,請自行輸入:‘) print ("下載的檔案為:"+str(‘%.2f‘ % (file_total/1024/1024))+"MB") print ("開始下載檔案:"+filename) t1 = threading.Thread(target=file1.downfile,args=(filename,)) t1.start() file1.downprogress(filename)
原始碼也上傳到http://down.51cto.com/data/2445550
總結與後續
這次是用Python類的形式來寫代碼,寫的時候有點不太習慣,可是更改或者維護代碼的時候,感覺挺方便。
這代碼只是在dos命令列下啟動並執行,接下來的任務是使用tkinter增加GUI介面
Python 實現下載進度條(不帶GUI介面)