Download di file http di base e salvataggio su disco in Python?


159

Sono nuovo di Python e ho seguito le domande e risposte su questo sito, per una risposta alla mia domanda. Tuttavia, sono un principiante e trovo difficile comprendere alcune delle soluzioni. Ho bisogno di una soluzione molto semplice.

Qualcuno potrebbe spiegare una semplice soluzione a "Scaricare un file tramite http" e "Salvarlo su disco, in Windows", per me?

Non sono nemmeno sicuro di come utilizzare i moduli shutil e os.

Il file che voglio scaricare è inferiore a 500 MB ed è un file di archivio .gz. Se qualcuno può spiegare come estrarre l'archivio e utilizzare anche i file in esso, sarebbe fantastico!

Ecco una soluzione parziale, che ho scritto da varie risposte combinate:

import requests
import os
import shutil

global dump

def download_file():
    global dump
    url = "http://randomsite.com/file.gz"
    file = requests.get(url, stream=True)
    dump = file.raw

def save_file():
    global dump
    location = os.path.abspath("D:\folder\file.gz")
    with open("file.gz", 'wb') as location:
        shutil.copyfileobj(dump, location)
    del dump

Qualcuno potrebbe indicare errori (livello principiante) e spiegare eventuali metodi più semplici per farlo?

Grazie!

Risposte:


207

Un modo semplice per scaricare un file è:

import urllib

testfile = urllib.URLopener()
testfile.retrieve("http://randomsite.com/file.gz", "file.gz")

Questo scarica un file da un sito Web e lo nomina file.gz. Questa è una delle mie soluzioni preferite, dal download di un'immagine tramite urllib e python .

Questo esempio usa il urllib libreria e recupererà direttamente il file da una fonte.


3
Ok grazie! Ma c'è un modo per farlo funzionare attraverso le richieste?
arvindch,

5
Qualche possibilità di salvare in /myfolder/file.gz?
John Snow,

17
Nessuna possibilità migliore di provarlo da soli, forse? :) Potrei farlo con successo testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Dharmit,

18
Questo è deprecato da Python 3.3 e la soluzione urllib.request.urlretrieve (vedi risposta sotto) è il modo "moderno"
MichielB

1
Qual è il modo migliore per aggiungere un nome utente e una password a questo codice? tks
Estefy,

110

Come menzionato qui :

import urllib
urllib.urlretrieve ("http://randomsite.com/file.gz", "file.gz")

EDIT:Se desideri ancora utilizzare le richieste, dai un'occhiata a questa domanda o questa .


1
urllib funzionerà, tuttavia, molte persone sembrano raccomandare l'uso di richieste su urllib. Perché?
arvindch,

2
requestsè estremamente utile rispetto a urllibquando si lavora con un'API REST. A meno che tu non stia cercando di fare molto di più, questo dovrebbe essere buono.
Dparpyani,

Ok, ora ho letto i link che hai fornito per l'utilizzo delle richieste. Sono confuso su come dichiarare il percorso del file, per il salvataggio del download. Come posso usare os e shutil per questo?
arvindch,

62
Per Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash

1
Non riesco a estrarre il codice di stato http con questo se il download non riesce
Aashish Thite

34

Uso wget .

Biblioteca semplice e buona se vuoi fare un esempio?

import wget

file_url = 'http://johndoe.com/download.zip'

file_name = wget.download(file_url)

Il modulo wget supporta le versioni python 2 e python 3


33

Quattro metodi che utilizzano wget, urllib e request.

#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile as profile
import urllib
import wget


url = 'https://tinypng.com/images/social/website.jpg'

def testRequest():
    image_name = 'test1.jpg'
    r = requests.get(url, stream=True)
    with open(image_name, 'wb') as f:
        for chunk in r.iter_content():
            f.write(chunk)

def testRequest2():
    image_name = 'test2.jpg'
    r = requests.get(url)
    i = Image.open(StringIO(r.content))
    i.save(image_name)

def testUrllib():
    image_name = 'test3.jpg'
    testfile = urllib.URLopener()
    testfile.retrieve(url, image_name)

def testwget():
    image_name = 'test4.jpg'
    wget.download(url, image_name)

if __name__ == '__main__':
    profile.run('testRequest()')
    profile.run('testRequest2()')
    profile.run('testUrllib()')
    profile.run('testwget()')

testRequest - 4469882 chiamate di funzione (4469842 chiamate primitive) in 20.236 secondi

testRequest2 - 8580 chiamate di funzione (8574 chiamate primitive) in 0,072 secondi

testUrllib - 3810 chiamate di funzione (3775 chiamate primitive) in 0,036 secondi

testwget - 3489 chiamate di funzione in 0,020 secondi


1
Come hai ricevuto il numero di chiamate di funzione?
Abdelhak,

30

Per Python3 + URLopener è obsoleto. E quando usato otterrai un errore come di seguito:

url_opener = urllib.URLopener () AttributeError: il modulo 'urllib' non ha attributo 'URLopener'

Allora prova:

import urllib.request 
urllib.request.urlretrieve(url, filename)

1
Strano ... Perché nessuno vota per questa risposta quando Python 2 è diventato obsoleto e solo questa soluzione dovrebbe funzionare correttamente ...
wowkin2

1
Concordato! Mi stavo togliendo i capelli dalle soluzioni precedenti. Vorrei poter votare 200 volte!
Yechiel K,

5

Soluzione esotica di Windows

import subprocess

subprocess.run("powershell Invoke-WebRequest {} -OutFile {}".format(your_url, filename), shell=True)

1

Ho iniziato questo percorso perché la wget di ESXi non è compilata con SSL e volevo scaricare un OVA dal sito Web di un fornitore direttamente sull'host ESXi che si trova dall'altra parte del mondo.

Ho dovuto disabilitare il firewall (pigro) / abilitare https modificando le regole (corretto)

creato lo script Python:

import ssl
import shutil
import tempfile
import urllib.request
context = ssl._create_unverified_context()

dlurl='https://somesite/path/whatever'
with urllib.request.urlopen(durl, context=context) as response:
    with open("file.ova", 'wb') as tmp_file:
        shutil.copyfileobj(response, tmp_file)

Le librerie ESXi sono un po 'abbinate ma il programma di installazione della donnola open source sembrava usare urllib per https ... quindi mi ha ispirato a seguire questo percorso


-5

Un altro modo pulito per salvare il file è questo:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")

Questo dovrebbe probabilmente essere urllib.urlretrieveo urllib.URLopener().retrieve, non chiaro, che intendevi qui.
mateor

9
Perché importare CSV se si sta semplicemente nominando un file?
Azeezah M
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.