Python 进度条和下载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15644964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python progress bar and downloads
提问by user1607549
I have a python script that launches a URL that is a downloadable file. Is there some way to have python use commandline to display the download progress as oppose to launching the browser?
我有一个 python 脚本,它启动一个可下载文件的 URL。有什么方法可以让 python 使用命令行来显示下载进度,而不是启动浏览器?
回答by Endophage
Updated for your sample url:
更新了您的示例网址:
I've just written a super simple (slightly hacky) approach to this for scraping pdfs off a certain site. Note, it only works correctly on unix based systems (linux, mac os) as powershell does not handle "\r"
我刚刚写了一个超级简单(有点hacky)的方法来从某个网站上抓取pdf。请注意,它只能在基于 unix 的系统(linux、mac os)上正常工作,因为 powershell 不处理“\r”
import requests
link = "http://indy/abcde1245"
file_name = "download.data"
with open(file_name, "wb") as f:
print "Downloading %s" % file_name
response = requests.get(link, stream=True)
total_length = response.headers.get('content-length')
if total_length is None: # no content length header
f.write(response.content)
else:
dl = 0
total_length = int(total_length)
for data in response.iter_content(chunk_size=4096):
dl += len(data)
f.write(data)
done = int(50 * dl / total_length)
sys.stdout.write("\r[%s%s]" % ('=' * done, ' ' * (50-done)) )
sys.stdout.flush()
It uses the requests libraryso you'll need to install that. This outputs something like the following into your console:
它使用requests 库,因此您需要安装它。这会在您的控制台中输出类似以下内容:
>Downloading download.data
>[============= ]
>下载download.data
>[============== ]
The progress bar is 52 characters wide in the script (2 characters are simply the []so 50 characters of progress). Each =represents 2% of the download.
脚本中的进度条有 52 个字符宽(2 个字符只是[]进度的 50 个字符)。每个=代表下载量的 2%。
回答by Rich Jones
You can use the 'clint' package (written by the same author as 'requests') to add a simple progress bar to your downloads like this:
您可以使用 ' clint' 包(与 ' requests' 由同一作者编写)为您的下载添加一个简单的进度条,如下所示:
from clint.textui import progress
r = requests.get(url, stream=True)
path = '/some/path/for/file.txt'
with open(path, 'wb') as f:
total_length = int(r.headers.get('content-length'))
for chunk in progress.bar(r.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1):
if chunk:
f.write(chunk)
f.flush()
which will give you a dynamic output which will look like this:
这将为您提供一个动态输出,如下所示:
[################################] 5210/5210 - 00:00:01
It should work on multiple platforms as well! You can also changethe bar to dots or a spinner with .dots and .mill instead of .bar.
它也应该适用于多个平台!您还可以将条形更改为点或带有 .dots 和 .mill 而不是 .bar 的微调器。
Enjoy!
享受!
回答by Tian Zhang
回答by Vamsidhar Muggulla
You can stream a downloads as it is here -> Stream a Download.
您可以在此处流式传输下载 ->流式传输下载。
Also you can Stream Uploads.
您也可以流式上传。
The most important streaming a request is done unless you try to access the response.content with just 2 lines
除非您尝试仅使用 2 行来访问 response.content,否则最重要的请求流已完成
for line in r.iter_lines():
if line:
print(line)
回答by Chris Chute
Python 3 with TQDM
带有 TQDM 的 Python 3
This is the suggested technique from the TQDM docs.
这是来自TQDM 文档的建议技术。
import urllib.request
from tqdm import tqdm
class DownloadProgressBar(tqdm):
def update_to(self, b=1, bsize=1, tsize=None):
if tsize is not None:
self.total = tsize
self.update(b * bsize - self.n)
def download_url(url, output_path):
with DownloadProgressBar(unit='B', unit_scale=True,
miniters=1, desc=url.split('/')[-1]) as t:
urllib.request.urlretrieve(url, filename=output_path, reporthook=t.update_to)
回答by Himanshu Binjola
#ToBeOptimized - BaselineIf you would like to puzzle your brain and hand craft the logic
#ToBeOptimized - Baseline如果你想解开你的大脑并手工制作逻辑
# Define Progress Bar function
# 定义进度条功能
def print_progressbar(total,current,barsize=60):
progress=int(current*barsize/total)
completed= str(int(current*100/total)) + '%'
print('[' , chr(9608)*progress,' ',completed,'.'*(barsize-progress),'] ',str(i)+'/'+str(total), sep='', end='\r',flush=True)
# Sample Code
# 示例代码
total= 6000
barsize=60
print_frequency=max(min(total//barsize,100),1)
print("Start Task..",flush=True)
for i in range(1,total+1):
if i%print_frequency == 0 or i == 1:
print_progressbar(total,i,barsize)
print("\nFinished",flush=True)
# Snapshot of Progress Bar :
# 进度条快照:
Below lines are for illustrations only. In command prompt you will see single progress bar showing incremental progress.
下面几行仅用于说明。在命令提示符下,您将看到显示增量进度的单个进度条。
[ 0%............................................................] 1/6000
[██████████ 16%..................................................] 1000/6000
[████████████████████ 33%........................................] 2000/6000
[██████████████████████████████ 50%..............................] 3000/6000
[████████████████████████████████████████ 66%....................] 4000/6000
[██████████████████████████████████████████████████ 83%..........] 5000/6000
[████████████████████████████████████████████████████████████ 100%] 6000/6000
Good Luck and Enjoy!
祝你好运和享受!
回答by casper.dcl
Sorry for being late with an answer; just updated the tqdmdocs:
抱歉迟到了答复;刚刚更新了tqdm文档:
https://github.com/tqdm/tqdm/#hooks-and-callbacks
https://github.com/tqdm/tqdm/#hooks-and-callbacks
Using urllib.urlretrieveand OOP:
使用urllib.urlretrieve和面向对象:
import urllib
from tqdm.auto import tqdm
class TqdmUpTo(tqdm):
"""Provides `update_to(n)` which uses `tqdm.update(delta_n)`."""
def update_to(self, b=1, bsize=1, tsize=None):
"""
b : Blocks transferred so far
bsize : Size of each block
tsize : Total size
"""
if tsize is not None:
self.total = tsize
self.update(b * bsize - self.n) # will also set self.n = b * bsize
eg_link = "https://github.com/tqdm/tqdm/releases/download/v4.46.0/tqdm-4.46.0-py2.py3-none-any.whl"
eg_file = eg_link.split('/')[-1]
with TqdmUpTo(unit='B', unit_scale=True, unit_divisor=1024, miniters=1,
desc=eg_file) as t: # all optional kwargs
urllib.urlretrieve(
eg_link, filename=eg_file, reporthook=t.update_to, data=None)
t.total = t.n
or using requests.getand file wrappers:
或使用requests.get和文件包装器:
import requests
from tqdm.auto import tqdm
eg_link = "https://github.com/tqdm/tqdm/releases/download/v4.46.0/tqdm-4.46.0-py2.py3-none-any.whl"
eg_file = eg_link.split('/')[-1]
response = requests.get(eg_link, stream=True)
with tqdm.wrapattr(open(eg_file, "wb"), "write", miniters=1,
total=int(response.headers.get('content-length', 0)),
desc=eg_file) as fout:
for chunk in response.iter_content(chunk_size=4096):
fout.write(chunk)
You could of course mix & match techniques.
你当然可以混合和匹配技术。


