Python 實現下載進度條(不帶GUI界面)

話不多說,先上圖
Python 實現下載進度條(不帶GUI界面)
該Python代碼可以實現獲取下載的文件名,下載文件的大小,下載速度等。

代碼關鍵點:

1、關於下載文件名的獲取:代碼裏使用兩種方式獲取:
(1) 通過Content-Disposition屬性,該屬性是作爲對下載文件的一個標識字段,存儲着下載文件名
Python 實現下載進度條(不帶GUI界面)
(2) 直接通過鏈接獲取,例如:sw.bos.baidu.com/sw-search-sp/software/8b23f8846df3d/BaiduMusicSetup.exe 文件後面直接就是文件名稱了。
2、關於下載文件大小的獲取:直接從HTTP的響應信息中獲取,在Content-Length中
Python 實現下載進度條(不帶GUI界面)
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 threading
import os
import requests
import time
import re
import urllib
def 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界面

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章