Descargar archivo desde la web en Python 3

Resuelto Bo Milanovich asked hace 13 años • 9 respuestas

Estoy creando un programa que descargará un archivo .jar (java) desde un servidor web, leyendo la URL especificada en el archivo .jad del mismo juego/aplicación. Estoy usando Python 3.2.1

Logré extraer la URL del archivo JAR del archivo JAD (cada archivo JAD contiene la URL del archivo JAR), pero como puede imaginar, el valor extraído es la cadena type().

Aquí está la función relevante:

def downloadFile(URL=None):
    import httplib2
    h = httplib2.Http(".cache")
    resp, content = h.request(URL, "GET")
    return content

downloadFile(URL_from_file)

Sin embargo, siempre recibo un error que dice que el tipo en la función anterior debe ser bytes y no cadena. Intenté usar URL.encode('utf-8') y también bytes(URL,encoding='utf-8'), pero siempre obtenía el mismo error o uno similar.

Básicamente, mi pregunta es ¿cómo descargar un archivo desde un servidor cuando la URL está almacenada en un tipo de cadena?

Bo Milanovich avatar Aug 30 '11 20:08 Bo Milanovich
Aceptado

Si desea obtener el contenido de una página web en una variable, solo readla respuesta de urllib.request.urlopen:

import urllib.request
...
url = 'http://example.com/'
response = urllib.request.urlopen(url)
data = response.read()      # a `bytes` object
text = data.decode('utf-8') # a `str`; this step can't be used if data is binary

La forma más sencilla de descargar y guardar un archivo es utilizar la urllib.request.urlretrievefunción:

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
urllib.request.urlretrieve(url, file_name)
import urllib.request
...
# Download the file from `url`, save it in a temporary directory and get the
# path to it (e.g. '/tmp/tmpb48zma.txt') in the `file_name` variable:
file_name, headers = urllib.request.urlretrieve(url)

Pero tenga en cuenta que urlretrievese considera heredado y podría quedar obsoleto (aunque no estoy seguro de por qué).

Entonces, la forma más correcta de hacer esto sería usar la urllib.request.urlopenfunción para devolver un objeto similar a un archivo que represente una respuesta HTTP y copiarlo a un archivo real usando shutil.copyfileobj.

import urllib.request
import shutil
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)

Si esto parece demasiado complicado, es posible que desees simplificarlo y almacenar toda la descarga en un bytesobjeto y luego escribirla en un archivo. Pero esto funciona bien sólo para archivos pequeños.

import urllib.request
...
# Download the file from `url` and save it locally under `file_name`:
with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    data = response.read() # a `bytes` object
    out_file.write(data)

Es posible extraer .gz(y tal vez otros formatos) datos comprimidos sobre la marcha, pero dicha operación probablemente requiera que el servidor HTTP admita el acceso aleatorio al archivo.

import urllib.request
import gzip
...
# Read the first 64 bytes of the file inside the .gz archive located at `url`
url = 'http://example.com/something.gz'
with urllib.request.urlopen(url) as response:
    with gzip.GzipFile(fileobj=response) as uncompressed:
        file_header = uncompressed.read(64) # a `bytes` object
        # Or do anything shown above using `uncompressed` instead of `response`.
Oleh Prypin avatar Aug 30 '2011 13:08 Oleh Prypin

Utilizo requestsel paquete siempre que quiero algo relacionado con solicitudes HTTP porque es muy fácil comenzar con su API:

primero, instalarrequests

$ pip install requests

entonces el código:

from requests import get  # to make GET request


def download(url, file_name):
    # open in binary mode
    with open(file_name, "wb") as file:
        # get request
        response = get(url)
        # write to file
        file.write(response.content)
Ali Faki avatar Jan 23 '2016 14:01 Ali Faki

Espero haber entendido bien la pregunta, que es: ¿cómo descargar un archivo de un servidor cuando la URL está almacenada en un tipo de cadena?

Descargo archivos y los guardo localmente usando el siguiente código:

import requests

url = 'https://www.python.org/static/img/python-logo.png'
fileName = 'D:\Python\dwnldPythonLogo.png'
req = requests.get(url)
file = open(fileName, 'wb')
for chunk in req.iter_content(100000):
    file.write(chunk)
file.close()
Ranvijay Kumar avatar Jan 18 '2016 20:01 Ranvijay Kumar

Puedes usar wget , que es una popular herramienta de descarga de shell para eso. https://pypi.python.org/pypi/wget Este será el método más simple ya que no es necesario abrir el archivo de destino. Aquí hay un ejemplo.

import wget
url = 'https://i1.wp.com/python3.codes/wp-content/uploads/2015/06/Python3-powered.png?fit=650%2C350'  
wget.download(url, '/Users/scott/Downloads/cat4.jpg') 
Lasith Niroshan avatar Jan 13 '2018 19:01 Lasith Niroshan