117 votes

Barre de progression Python et téléchargements

J'ai un script Python qui lance une URL qui est un fichier téléchargeable. Existe-t-il un moyen pour que Python affiche la progression du téléchargement plutôt que de lancer le navigateur ?

156voto

Endophage Points 6879

Je viens d'écrire une approche super simple (un peu bricolée) pour récupérer les PDF d'un certain site. Notez qu'elle ne fonctionne correctement que sur les systèmes basés sur Unix (Linux, mac os), car PowerShell ne gère pas l'option "\r" :

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

Il utilise le bibliothèque des demandes vous devrez donc l'installer. Cela donne quelque chose comme ce qui suit dans votre console :

>Downloading download.data

>[============= ]

La barre de progression fait 52 caractères de large dans le script (2 caractères sont simplement le [] soit 50 caractères de progression). Chaque = représente 2% du téléchargement.

83voto

Rich Jones Points 302

Vous pouvez utiliser l'option ' clint (écrit par le même auteur que 'requests') pour ajouter une simple barre de progression à vos téléchargements comme ceci :

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

ce qui vous donnera une sortie dynamique qui ressemblera à ceci :

[################################] 5210/5210 - 00:00:01

Il devrait également fonctionner sur plusieurs plateformes ! Vous peut également changer la barre en points ou un spinner avec .dots et .mill au lieu de .bar.

Profitez-en !

61voto

Chris Chute Points 631

Python 3 avec TQDM

C'est la technique suggérée par le Documents sur 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)

33voto

Yan QiDong Points 111

Il y a une réponse avec demande y tqdm .

import requests
from tqdm import tqdm

def download(url: str, fname: str):
    resp = requests.get(url, stream=True)
    total = int(resp.headers.get('content-length', 0))
    # Can also replace 'file' with a io.BytesIO object
    with open(fname, 'wb') as file, tqdm(
        desc=fname,
        total=total,
        unit='iB',
        unit_scale=True,
        unit_divisor=1024,
    ) as bar:
        for data in resp.iter_content(chunk_size=1024):
            size = file.write(data)
            bar.update(size)

Gist : https://gist.github.com/yanqd0/c13ed29e29432e3cf3e7c38467f42f51

11voto

Eric Grinstein Points 61

Une autre bonne option est wget :

import wget
wget.download('http://download.geonames.org/export/zip/US.zip')

La sortie ressemblera à ceci :

11% [........                                     ] 73728 / 633847

Source : https://medium.com/@petehouston/download-files-with-progress-in-python-96f14f6417a2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X