有
urlretrieve()将URL下载到文件并允许指定reporthook回调来报告进度的方法:
#!/usr/bin/env python3import sysfrom urllib.request import urlretrievedef reporthook(blocknum, blocksize, totalsize): readsofar = blocknum * blocksize if totalsize > 0: percent = readsofar * 1e2 / totalsize s = "r%5.1f%% %*d / %d" % ( percent, len(str(totalsize)), readsofar, totalsize) sys.stderr.write(s) if readsofar >= totalsize: # near the end sys.stderr.write("n") else: # total size is unknown sys.stderr.write("read %dn" % (readsofar,))urlretrieve(url, 'downloaded_file.py', reporthook)这是一个GUI进度栏:
import sysfrom threading import Event, Threadfrom tkinter import Tk, ttkfrom urllib.request import urlretrievedef download(url, filename): root = progressbar = quit_id = None ready = Event() def reporthook(blocknum, blocksize, totalsize): nonlocal quit_id if blocknum == 0: # started downloading def guiloop(): nonlocal root, progressbar root = Tk() root.withdraw() # hide progressbar = ttk.Progressbar(root, length=400) progressbar.grid() # show progress bar if the download takes more than .5 seconds root.after(500, root.deiconify) ready.set() # gui is ready root.mainloop() Thread(target=guiloop).start() ready.wait(1) # wait until gui is ready percent = blocknum * blocksize * 1e2 / totalsize # assume totalsize > 0 if quit_id is None: root.title('%%%.0f %s' % (percent, filename,)) progressbar['value'] = percent # report progress if percent >= 100: # finishing download quit_id = root.after(0, root.destroy) # close GUI return urlretrieve(url, filename, reporthook)download(url, 'downloaded_file.py')在Python
3.3上
urlretrieve()具有不同的
reporthook接口(请参阅问题16409)。要解决此问题,您可以通过访问以下界面
FancyURLopener:
from urllib.request import FancyURLopenerurlretrieve = FancyURLopener().retrieve
要在同一线程中更新进度条,可以内联
urlretrieve()代码:
from tkinter import Tk, ttkfrom urllib.request import urlopendef download2(url, filename): response = urlopen(url) totalsize = int(response.headers['Content-Length']) # assume correct header outputfile = open(filename, 'wb') def download_chunk(readsofar=0, chunksize=1 << 13): # report progress percent = readsofar * 1e2 / totalsize # assume totalsize > 0 root.title('%%%.0f %s' % (percent, filename,)) progressbar['value'] = percent # download chunk data = response.read(chunksize) if not data: # finished downloading outputfile.close() root.destroy() # close GUI else: outputfile.write(data) # save to filename # schedule to download the next chunk root.after(0, download_chunk, readsofar + len(data), chunksize) # setup GUI to show progress root = Tk() root.withdraw() # hide progressbar = ttk.Progressbar(root, length=400) progressbar.grid() # show progress bar if the download takes more than .5 seconds root.after(500, root.deiconify) root.after(0, download_chunk) root.mainloop()download2(url, 'downloaded_file.py')


