Quanto segue spiega come specificare l'URL di un'immagine, ZIP, PDF o altro file sul web in Python, scaricarlo e salvarlo come file locale.
- Scarica le immagini specificando l'URL.
- Esempio di codice
urllib.request.urlopen()
:Aprire l'URLopen()
:Scrivere su un file in modalità binaria- Un esempio di codice più semplice
- Scaricare file ZIP, PDF, ecc.
- Estrarre l'URL dell'immagine sulla pagina web.
- Se il numero è sequenziale
- Estratto con bella zuppa
- Scarica in batch più immagini da un elenco di URL
Scarica le immagini specificando l'URL.
Puoi usare la libreria standard solo per scaricare singoli file specificando i loro URL; non è richiesta alcuna installazione aggiuntiva.
Esempio di codice
Quello che segue è un esempio di una funzione che scarica e salva un file specificando l'URL e il percorso di destinazione, e il suo utilizzo. Questo codice è un po' prolisso per amore della spiegazione. Un semplice esempio è dato di seguito.
import os import pprint import time import urllib.error import urllib.request def download_file(url, dst_path): try: with urllib.request.urlopen(url) as web_file: data = web_file.read() with open(dst_path, mode='wb') as local_file: local_file.write(data) except urllib.error.URLError as e: print(e)
url = 'https://www.python.org/static/img/python-logo.png' dst_path = 'data/temp/py-logo.png' download_file(url, dst_path)
Per specificare la directory di destinazione e salvare il file con il nome del file URL, fare come segue
def download_file_to_dir(url, dst_dir): download_file(url, os.path.join(dst_dir, os.path.basename(url))) dst_dir = 'data/temp' download_file_to_dir(url, dst_dir)
Estrae il nome del file dall'URL con os.path.basename() e lo unisce alla directory specificata con os.path.join() per generare il percorso di destinazione.
Le sezioni seguenti descrivono la parte dell'acquisizione dei dati e la parte del salvataggio dei dati come file.
urllib.request.urlopen(): Aprire l'URL
Usate urllib.request.urlopen() per aprire l'URL e recuperare i dati. Si noti che urllib.urlopen() è stato deprecato in Python 2.6 e precedenti. urllib.request.urlretrieve() non è stato ancora deprecato, ma potrebbe esserlo in futuro.
Per evitare di fermarsi quando si verifica un'eccezione, catturate l'errore con try ed except.
Nell'esempio, urllib.error è importato e solo urllib.error.URLError è catturato esplicitamente. Il messaggio di errore viene visualizzato quando l'URL del file non esiste.
url_error = 'https://www.python.org/static/img/python-logo_xxx.png' download_file_to_dir(url_error, dst_dir) # HTTP Error 404: Not Found
Se volete anche catturare le eccezioni (FileNotFoundError, ecc.) quando salvate localmente, fate come segue.(urllib.error.URLError, FileNotFoundError)
È anche possibile utilizzare la libreria di terze parti Requests invece della libreria standard urllib per aprire l'url e ottenere i dati.
Scrivere su un file in modalità binaria in open()
I dati che possono essere ottenuti con urllib.request.urlopen() sono una stringa di byte (tipo bytes).
Open() con mode='wb' come secondo argomento scrive i dati come binario. w significa scrivere e b significa binario.
Un esempio di codice più semplice
Le dichiarazioni annidate con possono essere scritte in una volta sola, separate da virgole.
Usando questo, possiamo scrivere quanto segue.
def download_file(url, dst_path): try: with urllib.request.urlopen(url) as web_file, open(dst_path, 'wb') as local_file: local_file.write(web_file.read()) except urllib.error.URLError as e: print(e)
Scaricare file ZIP, PDF, ecc.
Gli esempi finora sono per il download e il salvataggio di file immagine, ma dato che stiamo semplicemente aprendo un file sul web e salvandolo come file locale, le stesse funzioni possono essere usate per altri tipi di file.
È possibile scaricare e salvare i file specificando l'URL.
url_zip = 'https://from-locas.com/sample_header.csv.zip' download_file_to_dir(url_zip, dst_dir) url_xlsx = 'https://from-locas/sample.xlsx' download_file_to_dir(url_xlsx, dst_dir) url_pdf = 'https://from-locas/sample1.pdf' download_file_to_dir(url_pdf, dst_dir)
Si noti che l'URL specificato in questa funzione deve essere un collegamento al file stesso.
Per esempio, nel caso di un file del repository di GitHub, il seguente URL ha un'estensione pdf ma è in realtà una pagina html. Se questo URL è specificato nella funzione di cui sopra, il sorgente html sarà scaricato.
- https://github.com/from-locals/python-snippets/blob/master/notebook/data/src/pdf/sample1.pdf
Il collegamento all'entità file è il seguente URL, che devi specificare se vuoi scaricare e salvare il file.
- https://github.com/from-locals/python-snippets/raw/master/notebook/data/src/pdf/sample1.pdf
Ci sono anche casi in cui l'accesso è limitato dall'agente utente, dal referrer, ecc, rendendo impossibile il download. Non garantiamo che tutti i file vengano scaricati.
È facile usare Requests per cambiare o aggiungere intestazioni di richiesta come l'agente utente.
Estrarre l'URL dell'immagine sulla pagina web.
Per scaricare tutte le immagini di una pagina in una volta sola, estrai prima gli URL delle immagini e crea una lista.
Se il numero è sequenziale
Se l'URL dell'immagine che volete scaricare è un semplice numero sequenziale, è facile. Se gli URL non sono solo numeri sequenziali ma hanno anche una certa regolarità, è più facile fare una lista di URL secondo le regole piuttosto che raschiare con Beautiful Soup (vedi sotto).
Usare la notazione di comprensione della lista.
- Articoli correlati:Usare la notazione di comprensione delle liste in Python
url_list = ['https://example.com/basedir/base_{:03}.jpg'.format(i) for i in range(5)] pprint.pprint(url_list) # ['https://example.com/basedir/base_000.jpg', # 'https://example.com/basedir/base_001.jpg', # 'https://example.com/basedir/base_002.jpg', # 'https://example.com/basedir/base_003.jpg', # 'https://example.com/basedir/base_004.jpg']
Nell'esempio precedente, {:03} è usato per un numero sequenziale di 3 cifre riempito con lo zero; {} è usato quando il riempimento con lo zero non è necessario, e {:05} è usato per un numero di 5 cifre invece di 3 cifre. Per maggiori informazioni sul metodo format di string str, vedi il seguente articolo.
- Articoli correlati:Conversione del formato in Python, formato (riempimento dello zero, notazione esponenziale, esadecimale, ecc.)
Inoltre, qui stiamo usando pprint per rendere l'output più facile da leggere.
Estratto con bella zuppa
Per estrarre gli URL delle immagini dalle pagine web in massa, usate Beautiful Soup.
import os import time import urllib.error import urllib.request from bs4 import BeautifulSoup url = 'https://it.from-locals.com/' ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) '\ 'AppleWebKit/537.36 (KHTML, like Gecko) '\ 'Chrome/55.0.2883.95 Safari/537.36 ' req = urllib.request.Request(url, headers={'User-Agent': ua}) html = urllib.request.urlopen(req) soup = BeautifulSoup(html, "html.parser") url_list = [img.get('data-src') for img in soup.find(class_='list').find_all('img')]
Nell'esempio, viene estratto l'URL dell'immagine in miniatura di questo sito web.
La struttura varia a seconda della pagina web, ma fondamentalmente si ottiene come segue.
- Ottiene un elenco di oggetti tag <img> specificando la classe, l'id, ecc. del blocco contenente le immagini multiple che si desidera scaricare.
soup.find(class_='list').find_all('img')
- Ottenere l'URL dell'immagine dall'elemento src o data-src del tag <img>.
img.get('data-src')
Il codice di esempio qui sopra è solo un esempio e non è garantito che funzioni.
Scarica in batch più immagini da un elenco di URL
Se avete una lista di URL, potete semplicemente girarla in un ciclo for e chiamare la funzione per scaricare e salvare il file con il primo URL mostrato. A causa della lista temporanea di URL, la chiamata alla funzione download_image_dir() è commentata qui.
download_dir = 'data/temp' sleep_time_sec = 1 for url in url_list: print(url) # download_file_dir(url, download_dir) time.sleep(sleep_time_sec) # https://example.com/basedir/base_000.jpg # https://example.com/basedir/base_001.jpg # https://example.com/basedir/base_002.jpg # https://example.com/basedir/base_003.jpg # https://example.com/basedir/base_004.jpg
Per non sovraccaricare il server, uso time.sleep() per creare un tempo di attesa per ogni download di immagini. L'unità è in secondi, quindi nell'esempio sopra, il modulo time è importato e usato.
L'esempio è per i file immagine, ma anche altri tipi di file possono essere scaricati insieme, purché siano elencati.