Question Comment télécharger un fichier via HTTP en utilisant Python?


J'ai un petit utilitaire que j'utilise pour télécharger un MP3 à partir d'un site Web sur un calendrier, puis construit / met à jour un fichier XML podcast que j'ai évidemment ajouté à iTunes.

Le traitement de texte qui crée / met à jour le fichier XML est écrit en Python. J'utilise wget dans un Windows .bat fichier pour télécharger le MP3 réel cependant. Je préférerais avoir tout l'utilitaire écrit en Python.

J'ai eu du mal à trouver un moyen de télécharger le fichier en Python, alors pourquoi ai-je eu recours à wget.

Alors, comment puis-je télécharger le fichier en utilisant Python?


690
2017-08-22 15:34


origine


Réponses:


En Python 2, utilisez urllib2 qui vient avec la bibliothèque standard.

import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()

C'est la manière la plus basique d'utiliser la bibliothèque, moins toute erreur de gestion. Vous pouvez également faire des choses plus complexes telles que changer les en-têtes. La documentation peut être trouvée ici.


388
2017-08-22 15:38



Un de plus, en utilisant urlretrieve:

import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

(pour Python 3+, utilisez 'import urllib.request' et urllib.request.urlretrieve)

Encore un autre, avec une "barre de progression"

import urllib2

url = "http://download.thinkbroadband.com/10MB.zip"

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

941
2017-08-22 16:19



En 2012, utilisez le bibliothèque de requêtes python

>>> import requests
>>> 
>>> url = "http://download.thinkbroadband.com/10MB.zip"
>>> r = requests.get(url)
>>> print len(r.content)
10485760

Tu peux courir pip install requests pour l'obtenir.

Les demandes ont de nombreux avantages par rapport aux alternatives car l'API est beaucoup plus simple. Ceci est particulièrement vrai si vous devez faire l'authentification. Urllib et Urllib2 sont assez inintéressant et douloureux dans ce cas.


2015-12-30

Les gens ont exprimé leur admiration pour la barre de progression. C'est cool, bien sûr. Il existe maintenant plusieurs solutions disponibles sur le marché, notamment tqdm:

from tqdm import tqdm
import requests

url = "http://download.thinkbroadband.com/10MB.zip"
response = requests.get(url, stream=True)

with open("10MB", "wb") as handle:
    for data in tqdm(response.iter_content()):
        handle.write(data)

C'est essentiellement l'implémentation @kvance décrite il y a 30 mois.


294
2018-05-24 20:08



import urllib2
mp3file = urllib2.urlopen("http://www.example.com/songs/mp3.mp3")
with open('test.mp3','wb') as output:
  output.write(mp3file.read())

le wb dans open('test.mp3','wb') ouvre un fichier (et efface tout fichier existant) en mode binaire afin que vous puissiez enregistrer des données avec lui au lieu de simplement du texte.


147
2017-08-22 15:58



Python 3

  • urllib.request.urlopen

    import urllib.request
    response = urllib.request.urlopen('http://www.example.com/')
    html = response.read()
    
  • urllib.request.urlretrieve

    import urllib.request
    urllib.request.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')
    

Python 2

  • urllib2.urlopen (Merci Corey)

    import urllib2
    response = urllib2.urlopen('http://www.example.com/')
    html = response.read()
    
  • urllib.urlretrieve (Merci PabloG)

    import urllib
    urllib.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')
    

63
2017-08-06 13:30



Une version améliorée du code PabloG pour Python 2/3:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import ( division, absolute_import, print_function, unicode_literals )

import sys, os, tempfile, logging

if sys.version_info >= (3,):
    import urllib.request as urllib2
    import urllib.parse as urlparse
else:
    import urllib2
    import urlparse

def download_file(url, dest=None):
    """ 
    Download and save a file specified by url to dest directory,
    """
    u = urllib2.urlopen(url)

    scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
    filename = os.path.basename(path)
    if not filename:
        filename = 'downloaded.file'
    if dest:
        filename = os.path.join(dest, filename)

    with open(filename, 'wb') as f:
        meta = u.info()
        meta_func = meta.getheaders if hasattr(meta, 'getheaders') else meta.get_all
        meta_length = meta_func("Content-Length")
        file_size = None
        if meta_length:
            file_size = int(meta_length[0])
        print("Downloading: {0} Bytes: {1}".format(url, 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 = "{0:16}".format(file_size_dl)
            if file_size:
                status += "   [{0:6.2f}%]".format(file_size_dl * 100 / file_size)
            status += chr(13)
            print(status, end="")
        print()

    return filename

if __name__ == "__main__":  # Only run if this file is called directly
    print("Testing with 10MB download")
    url = "http://download.thinkbroadband.com/10MB.zip"
    filename = download_file(url)
    print(filename)

18
2018-05-13 08:59



A écrit wget bibliothèque en pur Python juste à cet effet. Il est pompé urlretrieve avec ces fonctionnalités à partir de la version 2.0.


16
2017-09-25 17:55



utilisez le module wget:

import wget
wget.download('url')

16
2018-03-25 12:59



Je suis d'accord avec Corey, urllib2 est plus complet que urllib et devrait probablement être le module utilisé si vous voulez faire des choses plus complexes, mais pour rendre les réponses plus complètes, urllib est un module plus simple si vous voulez juste les bases:

import urllib
response = urllib.urlopen('http://www.example.com/sound.mp3')
mp3 = response.read()

Cela fonctionnera bien. Ou, si vous ne voulez pas traiter l'objet "réponse", vous pouvez appeler lis() directement:

import urllib
mp3 = urllib.urlopen('http://www.example.com/sound.mp3').read()

12
2017-08-22 15:58