以下代码将使用下载文件pycurl
并显示当前进度(作为文本):
import pycurl
# for displaying the output text
from sys import stderr as STREAM
# replace with your own url and path variables
url = "http://ovh.net/files/100Mb.dat"
path = 'test_file.dat'
# use kiB's
kb = 1024
# callback function for c.XFERINFOFUNCTION
def status(download_t, download_d, upload_t, upload_d):
STREAM.write('Downloading: {}/{} kiB ({}%)\r'.format(
str(int(download_d/kb)),
str(int(download_t/kb)),
str(int(download_d/download_t*100) if download_t > 0 else 0)
))
STREAM.flush()
# download file using pycurl
with open(path, 'wb') as f:
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.WRITEDATA, f)
# display progress
c.setopt(c.NOPROGRESS, False)
c.setopt(c.XFERINFOFUNCTION, status)
c.perform()
c.close()
# keeps progress onscreen after download completes
print()
输出应如下所示:
Downloading: 43563/122070 kiB (35%)
如果您想使用实际的进度条,也可以这样做。但这需要更多的工作。
以下代码使用tqdm
包生成进度条。它会在文件下载时实时更新,并显示下载速度和预计剩余时间。由于tqdm
工作方式的限制,requests
还需要包。这也与total_dl_d
变量是数组而不是整数的原因有关。
import pycurl
# needed to predict total file size
import requests
# progress bar
from tqdm import tqdm
# replace with your own url and path variables
url = "http://ovh.net/files/10Mb.dat"
path = 'test_file.dat'
# show progress % and amount in bytes
r = requests.get(url)
total_size = int(r.headers.get('content-length', 0))
block_size = 1024
# create a progress bar and update it manually
with tqdm(total=total_size, unit='iB', unit_scale=True) as pbar:
# store dotal dl's in an array (arrays work by reference)
total_dl_d = [0]
def status(download_t, download_d, upload_t, upload_d, total=total_dl_d):
# increment the progress bar
pbar.update(download_d - total[0])
# update the total dl'd amount
total[0] = download_d
# download file using pycurl
with open(path, 'wb') as f:
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(c.WRITEDATA, f)
# follow redirects:
c.setopt(c.FOLLOWLOCATION, True)
# custom progress bar
c.setopt(c.NOPROGRESS, False)
c.setopt(c.XFERINFOFUNCTION, status)
c.perform()
c.close()
对所描述问题的可能原因的解释:
(问题中没有提供代码,所以我不得不猜测一下究竟是什么导致了上述问题......)
基于变量名 ( fp
ie file_path
)...
文件写入 (WRITEDATA
) 问题可能是由于提供了文件路径 (str) 而不是文件对象 (io.BufferedWriter)。
根据我自己的经验...
文件XFERINFOFUNCTION
下载过程中反复调用回调。回调仅提供文件总大小和已下载的总大小作为参数。它不计算自上次调用以来的增量(差异)。进度条描述的问题(“进度条在一秒钟内达到 100% 并且 zip 文件尚未完成下载”)可能是由于(下载的)总量被用作增量update
时的数量预计金额。如果进度条每次都增加总量,那么它不会反映实际下载量。它将显示更大的数量。然后,它会超过100%,并且会出现各种故障。
资料来源: