libreria from python http urllib

from - urllib.urlencode python 3



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

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

Tengo una pequeña utilidad que uso para descargar un MP3 de un sitio web en un horario y luego compilo / actualizo 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. Sin embargo, uso wget dentro de un archivo .bat Windows para descargar el MP3 real. Sin embargo, preferiría tener toda la utilidad escrita en Python.

Sin embargo, luché por encontrar una manera de descargar el archivo en Python, y por eso recurrí a wget .

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


El código fuente puede ser:

import urllib sock = urllib.urlopen("http://diveintopython.org/") htmlSource = sock.read() sock.close() print htmlSource


En 2012, usa la biblioteca de peticiones python.

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

Puede ejecutar pip install requests para obtenerlo.

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

2015-12-30

La gente ha expresado admiración por la barra de progreso. Está bien, claro. Ahora hay varias soluciones disponibles, incluyendo 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.


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 cualquier manejo de errores. También puedes hacer cosas más complejas como cambiar los encabezados. La documentación se puede encontrar here.


En python3 puedes usar urllib3 y shutil libraires. Descárguelos utilizando pip o pip3 (dependiendo de si Python3 es predeterminado o no)

pip3 install urllib3 shutil

Entonces ejecuta este codigo

import urllib.request import shutil url = "http://www.somewebsite.com/something.pdf" output_file = "save_this_name.pdf" with urllib.request.urlopen(url) as response, open(output_file, ''wb'') as out_file: shutil.copyfileobj(response, out_file)

Tenga en cuenta que descarga urllib3 pero usa urllib en el código


Escribí lo siguiente, que funciona en vainilla Python 2 o Python 3.

import sys try: import urllib.request python3 = True except ImportError: import urllib2 python3 = False def progress_callback_simple(downloaded,total): sys.stdout.write( "/r" + (len(str(total))-len(str(downloaded)))*" " + str(downloaded) + "/%d"%total + " [%3.2f%%]"%(100.0*float(downloaded)/float(total)) ) sys.stdout.flush() def download(srcurl, dstfilepath, progress_callback=None, block_size=8192): def _download_helper(response, out_file, file_size): if progress_callback!=None: progress_callback(0,file_size) if block_size == None: buffer = response.read() out_file.write(buffer) if progress_callback!=None: progress_callback(file_size,file_size) else: file_size_dl = 0 while True: buffer = response.read(block_size) if not buffer: break file_size_dl += len(buffer) out_file.write(buffer) if progress_callback!=None: progress_callback(file_size_dl,file_size) with open(dstfilepath,"wb") as out_file: if python3: with urllib.request.urlopen(srcurl) as response: file_size = int(response.getheader("Content-Length")) _download_helper(response,out_file,file_size) else: response = urllib2.urlopen(srcurl) meta = response.info() file_size = int(meta.getheaders("Content-Length")[0]) _download_helper(response,out_file,file_size) import traceback try: download( "https://geometrian.com/data/programming/projects/glLib/glLib%20Reloaded%200.5.9/0.5.9.zip", "output.zip", progress_callback_simple ) except: traceback.print_exc() input()

Notas:

  • Es compatible con una devolución de llamada "barra de progreso".
  • Descargar es un archivo .zip de prueba de 4 MB de mi sitio web.

Escribió wget library en Python puro solo para este propósito. Se bombea urlretrieve con estas características a partir de la versión 2.0.


Esto puede ser un poco tarde, pero vi el código de pabloG y no pude evitar agregar un os.system (''cls'') para que se viera INCREÍBLE! Echale un vistazo :

import urllib2,os 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) os.system(''cls'') 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()

Si se ejecuta en un entorno que no sea Windows, tendrá que usar algo que no sea ''cls''. En MAC OS X y Linux debería estar ''claro''.


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

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

Funcionará bien. O, si no desea tratar el objeto de "respuesta", puede llamar a read () directamente:

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


Las siguientes son las llamadas más utilizadas para descargar archivos en python:

  1. urllib.urlretrieve (''url_to_file'', file_name)

  2. urllib2.urlopen(''url_to_file'')

  3. requests.get(url)

  4. wget.download(''url'', file_name)

Nota: se encuentra que urlopen y urlretrieve tienen un rendimiento relativamente malo con la descarga de archivos grandes (tamaño> 500 MB). requests.get almacena el archivo en memoria hasta que se completa la descarga.


Puedes usar PycURL en Python 2 y 3.

import pycurl FILE_DEST = ''pycurl.html'' FILE_SRC = ''http://pycurl.io/'' with open(FILE_DEST, ''wb'') as f: c = pycurl.Curl() c.setopt(c.URL, FILE_SRC) c.setopt(c.WRITEDATA, f) c.perform() c.close()


Si la velocidad es importante para usted, hice una pequeña prueba de rendimiento para los módulos urllib y wget , y con respecto a wget probé una vez con la barra de estado y una vez sin. Tomé tres archivos diferentes de 500 MB para probarlos (diferentes archivos, para eliminar la posibilidad de que haya un poco de almacenamiento en caché bajo el capó). Probado en la máquina debian, con python2.

Primero, estos son los resultados (son similares en diferentes ejecuciones):

$ python wget_test.py urlretrive_test : starting urlretrive_test : 6.56 ============== wget_no_bar_test : starting wget_no_bar_test : 7.20 ============== wget_with_bar_test : starting 100% [......................................................................] 541335552 / 541335552 wget_with_bar_test : 50.49 ==============

La forma en que realicé la prueba es usando el decorador "perfil". Este es el código completo:

import wget import urllib import time from functools import wraps def profile(func): @wraps(func) def inner(*args): print func.__name__, ": starting" start = time.time() ret = func(*args) end = time.time() print func.__name__, ": {:.2f}".format(end - start) return ret return inner url1 = ''http://host.com/500a.iso'' url2 = ''http://host.com/500b.iso'' url3 = ''http://host.com/500c.iso'' def do_nothing(*args): pass @profile def urlretrive_test(url): return urllib.urlretrieve(url) @profile def wget_no_bar_test(url): return wget.download(url, out=''/tmp/'', bar=do_nothing) @profile def wget_with_bar_test(url): return wget.download(url, out=''/tmp/'') urlretrive_test(url1) print ''=============='' time.sleep(1) wget_no_bar_test(url2) print ''=============='' time.sleep(1) wget_with_bar_test(url3) print ''=============='' time.sleep(1)

urllib parece ser el más rápido


Si tiene instalado wget, puede usar parallel_sync.

pip instalar parallel_sync

from parallel_sync import wget urls = [''http://something.png'', ''http://somthing.tar.gz'', ''http://somthing.zip''] wget.download(''/tmp'', urls) # or a single file: wget.download(''/tmp'', urls[0], filenames=''x.zip'', extract=True)

Doc: https://pythonhosted.org/parallel_sync/pages/examples.html

Esto es bastante poderoso. Puede descargar archivos en paralelo, reintentar en caso de falla, e incluso puede descargar archivos en una máquina remota.


Sin embargo, la forma simple Python 2 & Python 3 compatible con Python 2 & Python 3 incluye six bibliotecas:

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


Solo por estar completo, también es posible llamar a cualquier programa para recuperar archivos utilizando el paquete de subprocess . Los programas dedicados a recuperar archivos son más poderosos que las funciones de Python como urlretrieve , por ejemplo, wget puede descargar directorios de forma recursiva ( -R ), puede manejar FTP, redireccionamientos, proxies HTTP, puede evitar volver a descargar archivos existentes ( -nc ), y aria2 puede paralelizar las descargas.

import subprocess subprocess.check_output([''wget'', ''-O'', ''example_output_file.html'', ''https://example.com''])

En Jupyter Notebook, también se puede llamar a programas directamente con el ! sintaxis:

!wget -O example_output_file.html https://example.com


También puede obtener la retroalimentación de progreso con urlretrieve:

def report(blocknr, blocksize, size): current = blocknr*blocksize sys.stdout.write("/r{0:.2f}%".format(100.0*current/size)) def downloadFile(url): print "/n",url fname = url.split(''/'')[-1] print fname urllib.urlretrieve(url, fname, report)


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)

Otra más, 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()


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)


urlretrieve y requests.get es simple, sin embargo la realidad no. He recuperado datos para sitios de parejas, incluidos texto e imágenes, los dos anteriores probablemente resuelven la mayoría de las tareas. pero para una solución más universal sugiero el uso de urlopen. Como se incluye en la biblioteca estándar de Python 3, su código podría ejecutarse en cualquier máquina que ejecute Python 3 sin preinstalar el sitio

import urllib.request url_request = urllib.request.Request(url, headers=headers) url_connect = urllib.request.urlopen(url_request) len_content = url_content.length #remember to open file in bytes mode with open(filename, ''wb'') as f: while True: buffer = url_connect.read(buffer_size) if not buffer: break #an integer value of size of written data data_wrote = f.write(buffer) #you could probably use with-open-as manner url_connect.close()

Esta respuesta proporciona una solución a HTTP 403 Prohibido cuando se descarga un archivo a través de http usando Python. He intentado solo solicitudes y módulos urllib, el otro módulo puede proporcionar algo mejor, pero este es el que utilicé para resolver la mayoría de los problemas.


utilizar el módulo wget:

import wget wget.download(''url'')


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

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


import os,requests def download(url): get_response = requests.get(url,stream=True) file_name = url.split("/")[-1] with open(file_name, ''wb'') as f: for chunk in get_response.iter_content(chunk_size=1024): if chunk: # filter out keep-alive new chunks f.write(chunk) download("https://example.com/example.jpg")