Frage

Ich schreibe eine kleine Anwendung zum Herunterladen von Dateien über http (wie zum Beispiel beschrieben). Hier).

Ich möchte auch eine kleine Download-Fortschrittsanzeige einbauen, die den Prozentsatz des Download-Fortschritts anzeigt.

Hier ist, was ich mir ausgedacht habe:

    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()

Ausgabe:MeinDateiname...9 %

Irgendwelche anderen Ideen oder Empfehlungen dazu?

Etwas störend ist der blinkende Cursor im Terminal auf der ersten Ziffer der Prozentzahl.Gibt es eine Möglichkeit, dies zu verhindern?Gibt es eine Möglichkeit, den Cursor auszublenden?

BEARBEITEN:

Hier eine bessere Alternative mit einer globalen Variablen für den Dateinamen in dlProgress und dem Code „ “:

    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()

Ausgabe:MeinDateiname...9%

Und der Cursor erscheint am ENDE der Zeile.Viel besser.

War es hilfreich?

Lösung

Es gibt eine Textfortschrittsbalkenbibliothek für Python unter http://pypi.python.org/pypi/progressbar/2.2 die für Sie nützlich sein könnten:

Diese Bibliothek bietet einen Textmodus-Fortschrittsbalken.Dies wird typischerweise verwendet, um den Fortschritt eines lang laufenden Vorgangs anzuzeigen und einen visuellen Hinweis darauf zu geben, dass die Verarbeitung im Gange ist.

Die ProgressBar-Klasse verwaltet den Fortschritt und das Format der Zeile wird durch eine Reihe von Widgets vorgegeben.Ein Widget ist ein Objekt, das je nach Fortschrittsstatus unterschiedlich angezeigt werden kann.Es gibt drei Arten von Widgets:- eine Zeichenfolge, die sich immer zeigt;- ein ProgressBarWidget, das bei jedem Aufruf seiner Update-Methode einen anderen Wert zurückgeben kann;und – ein ProgressBarWidgetHFill, das wie ProgressBarWidget ist, außer dass es erweitert wird, um die verbleibende Breite der Linie auszufüllen.

Das Progressbar-Modul ist sehr einfach zu bedienen und dennoch sehr leistungsstark.Und unterstützt automatisch Funktionen wie die automatische Größenänderung, sofern verfügbar.

Andere Tipps

Sie könnten auch Folgendes versuchen:

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

Verwenden Sie einen einzelnen Wagenrücklauf am Anfang Ihrer Zeichenfolge anstelle mehrerer Rückschritte.Ihr Cursor blinkt immer noch, aber er blinkt nach dem Prozentzeichen und nicht unter der ersten Ziffer, und mit einem Steuerzeichen anstelle von drei kann es sein, dass es weniger flackert.

Hier ist der Code, mit dem ich es zum Laufen gebracht habe:

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) )

Wenn Sie die verwenden curses Paket haben Sie eine viel größere Kontrolle über die Konsole.Außerdem ist der Code komplexer und wahrscheinlich unnötig, es sei denn, Sie entwickeln eine große konsolenbasierte App.

Für eine einfache Lösung können Sie das sich drehende Rad jederzeit am Ende der Statusmeldung (der Zeichenfolge) platzieren |, \, -, / was unter dem blinkenden Cursor tatsächlich gut aussieht.

Ich habe diesen Code verwendet:

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()
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)

Bei kleinen Dateien benötigen Sie möglicherweise diese Zeilen, um verrückte Prozentsätze zu vermeiden:

sys.stdout.write(" %2d%%" % Prozent)

sys.stdout.flush()

Prost

So habe ich es gemacht, das könnte dir helfen:https://github.com/mouuff/MouDownloader/blob/master/api/download.py

Wie üblich zu spät zur Party.Hier ist eine Implementierung, die wie der Kern die Fortschrittsmeldung unterstützt 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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top