Pregunta ¿Cómo descargo un archivo a través de HTTP usando Python?


Tengo una pequeña utilidad que utilizo para descargar un MP3 de un sitio web en un horario y luego construyo / actualiza un archivo XML de podcast que obviamente he agregado a iTunes.

El procesamiento de texto que crea / actualiza el archivo XML está escrito en Python. Yo uso wget dentro de un Windows .bat archivo para descargar el MP3 real sin embargo. Sin embargo, preferiría tener toda la utilidad escrita en Python.

Sin embargo, tuve problemas para encontrar la forma de cargar el archivo en Python, por lo que recurrí a wget.

Entonces, ¿cómo descargo el archivo usando Python?


690
2017-08-22 15:34


origen


Respuestas:


En Python 2, use urllib2 que viene con la biblioteca estándar.

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

Esta es la forma más básica de usar la biblioteca, menos el manejo de errores. También puede hacer cosas más complejas como cambiar encabezados. La documentación se puede encontrar aquí.


388
2017-08-22 15:38



Una más, usando urlretrieve:

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

(para Python 3+ use 'import urllib.request' y urllib.request.urlretrieve)

Sin embargo, otro, con una "barra de progreso"

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, use el python solicita biblioteca

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

Tu puedes correr pip install requests para conseguirlo.

Las solicitudes tienen muchas ventajas sobre las alternativas porque la API es mucho más simple. Esto es especialmente cierto si tiene que hacer la autenticación. urllib y urllib2 son bastante intuitivos y dolorosos en este caso.


2015-12-30

La gente ha expresado su admiración por la barra de progreso. Es genial, claro. Hay varias soluciones listas para usar, que incluyen 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)

Esta es esencialmente la implementación @kvance descrita hace 30 meses.


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

los wb en open('test.mp3','wb') abre un archivo (y borra cualquier archivo existente) en modo binario para que pueda guardar datos con él en lugar de solo texto.


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

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

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

63
2017-08-06 13:30



Una versión mejorada del código PabloG para 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



Escribió wget biblioteca en Python puro solo para este propósito. Está bombeado urlretrieve con estas características a partir de la versión 2.0.


16
2017-09-25 17:55



utilizar el módulo wget:

import wget
wget.download('url')

16
2018-03-25 12:59



Estoy de acuerdo con Corey, urllib2 es más completo que urllib y probablemente debería ser el módulo utilizado si desea hacer cosas más complejas, pero para hacer que las respuestas sean más completas, urllib es un módulo más simple si desea solo lo básico:

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

Funcionará bien O bien, si no desea tratar con el objeto "respuesta" puede llamar leer() directamente:

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

12
2017-08-22 15:58