Python può rivelarsi come un ottimo aiutante nell'implementazione di web app nel compito di reperire le immagini di esempio usate durante lo sviluppo.
Supponiamo di voler offrire ai nostri clienti un prototipo il più simile possibile al risultato finale e che per far ciò dobbiamo reperire numerose immagini di esempio.
Effettuare il download delle immagini è un compito che può essere automatizzato con Python seguendo una procedura precisa:
- Individuiamo una pagina di un sito che offra immagini prive di copyright. Eviteremo in questo tutorial di utilizzare le API di un servizio come Unsplash a scopo puramente didattico.
- Esaminiamo il sorgente HTML della pagina e verifichiamo come sono inserite le immagini. Molti siti infatti offrono un'anteprima delle immagini nella pagina di riepilogo e l'immagine effettiva nella pagina di dettaglio.
- Reperiamo la pagina iniziale con il modulo
requests
e estraiamo gli URL delle pagine di dettaglio con il moduloBeautifulSoup
. - Dopo aver studiato il codice sorgente di una pagina di dettaglio, effettuiamo una richiesta GET su ciascun URL e estraiamo dalla pagina il valore dell'attributo
src
dell'immagine principale, ossia l'URL dell'immagine che vogliamo scaricare. - Scarichiamo quindi l'immagine principale preservandone il nome originale.
La prima funzione che andremo a definire è quella che estrare il nome del file contenuto in un URL.
import os
from urllib.parse import urlsplit
def get_filename_from_url(url=None):
if url is None:
return None
urlpath = urlsplit(url).path
return os.path.basename(urlpath)
La funzione core urlsplit()
estrae il percorso da un URL assoluto. La proprietà path
viene quindi usata dal metodo basename()
per ottenere il solo nome del file compreso di estensione.
Ora possiamo creare la funzione che effettua il download di una pagina web e restituisce il suo codice HTML come stringa.
import requests
def get_page(url):
try:
r = requests.get(url, allow_redirects=True)
return r.text
except requests.exceptions.RequestException as e:
return ''
Se la richiesta HTTP fallisce, viene restituita una stringa vuota. Ora possiamo definire la funzione che effettua il download dell'immagine e la salva nel filesystem.
import requests
def download_image(url, destination_path):
if url is None:
return False
try:
res = requests.get(url, allow_redirects=True)
data = res.content
with open(destination_path, 'wb') as img:
img.write(data)
return True
except requests.exceptions.RequestException:
return False
La proprietà content
della risposta viene qui salvata nel filesystem usando la modalità binaria in scrittura poichè si tratta di immagini. Questa funzione restituisce un valore booleano che indica l'esito dell'operazione.
A questo punto dobbiamo estrarre gli elementi della pagina usando i loro attributi HTML.
from bs4 import BeautifulSoup
def get_page_elements(html, attrs):
soup = BeautifulSoup(html, 'html.parser')
elements = soup.find_all(attrs=attrs)
return elements
Poichè stiamo cercando più elementi nel documento, usiamo il metodo find_all()
passandogli come parametro il dizionario attrs
che ci permette di specificare il nome dell'attributo e il suo valore.
Possiamo quindi definire la funzione principale:
def download_images(start_url, link_class, img_class):
start_page = get_page(start_url)
if not start_page:
return []
detail_links = get_page_elements(start_page, {'class': link_class})
downloaded_images = []
for dlink in detail_links:
dpage_url = dlink.get('href')
lnk_page = get_page(dpage_url)
if not lnk_page:
continue
imgs = get_page_elements(lnk_page, {'class': img_class})
for img in imgs:
src = img.get('src')
name = get_filename_from_url(src)
download = download_image(src, f'./static/{name}')
if download:
downloaded_images.append(name)
return downloaded_images
Questa funzione restituisce una lista contenente i nomi delle immagini scaricate o una lista vuota in caso di errore. Possiamo usare questa funzione come segue:
def main():
images = download_images('https://site.tld/images/', 'detail', 'pic')
print(images)
if __name__ == '__main__':
main()
In conclusione, Python si rivela essere un ottimo strumento per velocizzare l'acquisizione delle assets per creare i prototipi delle web app da presentare.