Подтвердить что ты не робот

Как написать индикатор прогресса загрузки в Python?

Я пишу небольшое приложение для загрузки файлов через http (как, например, описано здесь).

Я также хочу включить небольшой индикатор прогресса загрузки, показывающий процент выполнения загрузки.

Вот что я придумал:

    sys.stdout.write(rem_file + "...")    
    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("%2d%%" % percent)
      sys.stdout.write("\b\b\b")
      sys.stdout.flush()

Выход: MyFileName... 9%

Любые другие идеи или рекомендации для этого?

Одна вещь, которая несколько раздражает, - это мигающий курсор в терминале на первой цифре процента. Есть ли способ предотвратить это? Есть ли способ скрыть курсор?

EDIT:

Вот лучшая альтернатива, использующая глобальную переменную для имени файла в dlProgress и код '\ r':

    global rem_file # global variable to be used in dlProgress

    urllib.urlretrieve(rem_file, loc_file, reporthook=dlProgress)

    def dlProgress(count, blockSize, totalSize):
      percent = int(count*blockSize*100/totalSize)
      sys.stdout.write("\r" + rem_file + "...%d%%" % percent)
      sys.stdout.flush()

Выход: MyFileName... 9%

И курсор отображается в конце END. Гораздо лучше.

4b9b3361

Ответ 1

Там, где вы можете найти полезную информацию, для библиотеки python на http://pypi.python.org/pypi/progressbar/2.2 существует библиотека текстовых индикаторов выполнения:

В этой библиотеке отображается панель прогресса текстового режима. Это типично используется для отображения прогресса продолжительной работы, обеспечивая визуальный ключ, который обрабатывает процесс.

Класс ProgressBar управляет ходом, а формат строки задается рядом виджетов. Виджет - это объект, который может отображаться в зависимости от состояния хода. Существует три типа виджета: - строка, которая всегда показывает себя; - ProgressBarWidget, который может возвращать различное значение при каждом вызове метода обновления; и - ProgressBarWidgetHFill, который похож на ProgressBarWidget, за исключением того, что он расширяется, чтобы заполнить оставшуюся ширину строки.

Модуль progressbar очень прост в использовании, но очень мощный. И автоматически поддерживает такие функции, как автоматическое изменение размера, когда доступно.

Ответ 2

Вы также можете попробовать:

sys.stdout.write("\r%2d%%" % percent)
sys.stdout.flush()

Использование одного возврата каретки в начале строки, а не нескольких обратных пространств. Ваш курсор все равно будет мигать, но он будет мигать после знака процента, а не под первой цифрой, а с одним контрольным символом вместо трех вы можете получить меньше мерцания.

Ответ 3

Если вы используете пакет curses, у вас есть гораздо больший контроль над консолью. Это также связано с более высокой стоимостью сложности кода и, вероятно, не нужно, если вы не разрабатываете большое консольное приложение.

Для простого решения вы всегда можете поместить вращающееся колесо в конец посыльного статуса (последовательность символов |, \, -, /, которая на самом деле выглядит красиво под мигающим курсором.

Ответ 4

Для чего это стоит, вот код, который я использовал для его работы:

from urllib import urlretrieve
from progressbar import ProgressBar, Percentage, Bar

url = "http://......."
fileName = "file"
pbar = ProgressBar(widgets=[Percentage(), Bar()])
urlretrieve(url, fileName, reporthook=dlProgress)

def dlProgress(count, blockSize, totalSize):
    pbar.update( int(count * blockSize * 100 / totalSize) )

Ответ 5

Я использовал этот код:

url = (<file location>)
file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)

file_size_dl = 0
block_sz = 8192
while True:
    buffer = u.read(block_sz)
    if not buffer:
        break

    file_size_dl += len(buffer)
    f.write(buffer)
    status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
    status = status + chr(8)*(len(status)+1)
    print status,

f.close()

Ответ 6

Для небольших файлов вам могут понадобиться эти строки, чтобы избежать сумасшедших процентов:

sys.stdout.write( "\ r% 2d %%" % процентов)

sys.stdout.flush()

Приветствия

Ответ 8

Поздно к партии, как обычно. Здесь реализована реализация, которая поддерживает отчетность, такую ​​как ядро ​​ urlretrieve:

import urllib2

def urlretrieve(urllib2_request, filepath, reporthook=None, chunk_size=4096):
    req = urllib2.urlopen(urllib2_request)

    if reporthook:
        # ensure progress method is callable
        if hasattr(reporthook, '__call__'):
            reporthook = None

        try:
            # get response length
            total_size = req.info().getheaders('Content-Length')[0]
        except KeyError:
            reporthook = None

    data = ''
    num_blocks = 0

    with open(filepath, 'w') as f:
        while True:
            data = req.read(chunk_size)
            num_blocks += 1
            if reporthook:
                # report progress
                reporthook(num_blocks, chunk_size, total_size)
            if not data:
                break
            f.write(data)

    # return downloaded length
    return len(data)

Ответ 9

def download_progress_hook(count, blockSize, totalSize):
  """A hook to report the progress of a download. This is mostly intended for users with slow internet connections. Reports every 5% change in download progress.
  """
  global last_percent_reported
  percent = int(count * blockSize * 100 / totalSize)

  if last_percent_reported != percent:
    if percent % 5 == 0:
      sys.stdout.write("%s%%" % percent)
      sys.stdout.flush()
    else:
      sys.stdout.write(".")
      sys.stdout.flush()

    last_percent_reported = percent

urlretrieve(url, filename, reporthook=download_progress_hook)