1. Logging
Oggi ci immergiamo in un argomento che probabilmente ti salverà un sacco di tempo e pazienza: il logging e la gestione degli errori. Anche il programmatore più esperto non è immune agli errori, e il tuo compito è rendere quegli errori prevedibili e gestibili. Immagina di essere un archeologo in una spedizione e il tuo compito è proteggere la squadra da crolli inaspettati o trappole pericolose: il logging e la gestione degli errori sono la tua bussola e il tuo scudo in questa missione rischiosa!
Quando parliamo di logging in programmazione, intendiamo il processo di registrazione delle informazioni sull'esecuzione del programma. Questi sono processi che avvengono all'interno del tuo codice e possono non essere visibili subito. Registrando i log, lasci indizi per te stesso, proprio come Hansel e Gretel lasciavano briciole di pane nella foresta per tornare a casa.
Installazione e configurazione del logging
Iniziamo con gli strumenti base in Python. Per il logging utilizzeremo il modulo integrato logging
. Questo è il tuo coltellino svizzero per registrare informazioni sull'esecuzione del programma.
import logging
# Configurazione del logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Esempio di utilizzo
logging.info("Inizio dell'esecuzione dello script")
logging.error("Questo è un errore")
Quali sono i livelli di logging?
- DEBUG: informazioni più dettagliate, solitamente utili solo per diagnosticare problemi.
- INFO: conferma che i processi stanno funzionando come previsto.
- WARNING: indica qualcosa di inatteso o potenzialmente problematico, ma il programma funziona ancora.
- ERROR: solo errori seri che causano un fallimento nella funzione.
Puoi configurare il livello di logging per filtrare le informazioni. Ad esempio, se ti interessano solo errori e avvisi, imposta il livello su logging.WARNING
.
Esempio di logging in Selenium
Vediamo come il logging può essere applicato in un progetto con Selenium:
from selenium import webdriver
# Configurazione del logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
try:
logging.info("Inizializzazione del driver Chrome")
driver = webdriver.Chrome()
logging.info("Apertura della pagina Python.org")
driver.get("https://www.python.org")
logging.info("Esecuzione completata con successo")
except Exception as e:
logging.error(f"Si è verificato un errore: {e}")
finally:
driver.quit()
Questo esempio mostra come integrare il logging nel tuo script Selenium per monitorare la sua esecuzione. Usiamo try
, except
, e finally
per gestire gli errori — ne parliamo più dettagliatamente sotto.
2. Gestione degli errori in Selenium
In programmazione, come nella vita, gli errori sono inevitabili. Tuttavia, possiamo controllare come reagiamo. Usare try
, except
, else
, e finally
ci permette di intercettare e gestire gli errori elegantemente.
Ripassiamo la gestione delle eccezioni
Ripetiamo come funziona la gestione delle eccezioni:
try:
# Codice che potrebbe generare un'eccezione
result = 10 / 0
except ZeroDivisionError as e:
# Codice eseguito se viene generata l'eccezione ZeroDivisionError
logging.error("Divisione per zero impossibile!")
else:
# Codice eseguito se non viene generata un'eccezione
logging.info("Operazione completata con successo")
finally:
# Codice eseguito sempre
logging.info("Operazioni completate")
Il tuo codice nel blocco try
verrà eseguito. Se si verifica un errore di tipo ZeroDivisionError
, il codice nel blocco except
verrà eseguito e il programma non si bloccherà. Il blocco else
viene utilizzato per eseguire il codice se non si è verificata alcuna eccezione. Infine, il blocco finally
viene sempre eseguito, indipendentemente dal fatto che ci sia stato un errore o meno.
Gestione degli errori in Selenium
Selenium offre una serie di eccezioni integrate per gestire diverse situazioni. Ecco alcune eccezioni utili e come usarle.
-
NoSuchElementException
: si verifica se l'elemento non è stato trovato. Usalo per verificare la disponibilità degli elementi.Pythontry: element = driver.find_element(By.ID, "element_id") except NoSuchElementException: logging.warning("Elemento con ID 'element_id' non trovato.")
-
TimeoutException
: si verifica se l'elemento atteso non compare sulla pagina entro il tempo impostato. Usato per gestire le attese.Pythonfrom selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "element_id")) ) except TimeoutException: logging.error("Attesa dell'elemento con ID 'element_id' terminata con errore.")
-
ElementClickInterceptedException
: si verifica quando un elemento è bloccato da un altro elemento e non può essere cliccato. Utile quando si clicca su elementi bloccati da popup.Pythonfrom selenium.common.exceptions import ElementClickInterceptedException try: driver.find_element(By.ID, "button_id").click() except ElementClickInterceptedException: logging.warning("Elemento bloccato da un altro elemento, clic non possibile.")
Riprova e logica di recupero
Per aumentare la resilienza del tuo script, puoi implementare un meccanismo di tentativi in caso di errori. Ad esempio, se un sito è temporaneamente non disponibile o un elemento non è stato trovato, lo script può provare ad eseguire l'azione più volte prima di terminare con un errore.
import time
def retry_find_element(driver, by, value, retries=3):
attempt = 0
while attempt < retries:
try:
element = driver.find_element(by, value)
logging.info(f"Elemento trovato: {value}")
return element
except NoSuchElementException:
attempt += 1
logging.warning(f"Tentativo {attempt} non riuscito, riprova tra 2 secondi...")
time.sleep(2)
logging.error(f"Elemento non trovato dopo {retries} tentativi.")
return None
Consigli per la resilienza e l'affidabilità degli script
- Usa gli explicit waits: Configura attese esplicite per gli elementi che non appaiono immediatamente. Questo ridurrà il numero di errori dovuti ai ritardi di caricamento.
- Implementa blocchi try-except in ogni fase: Ciò ti consentirà di registrare gli errori ed evitare l'interruzione dello script in caso di piccoli problemi.
- Ritenta per i passaggi critici: Se un errore potrebbe essere temporaneo, configura più tentativi con un intervallo di pochi secondi.
- Registra ogni fase: Registrare ogni fase chiave aiuta ad analizzare l'esecuzione dello script e a trovare errori nascosti.
- Configura notifiche per gli errori critici: Ad esempio, puoi inviare un'email o un messaggio in chat se nei log viene registrato un errore di livello CRITICAL.
3. Loggare con criterio
Ora che abbiamo imparato a registrare e gestire gli errori, facciamo un passo in più e vediamo come ottenere il massimo dai log.
Scelta della posizione e del formato dei log
Usa un file per conservare i log, se vuoi salvarli per analisi future. È come tenere un diario che puoi rileggere e analizzare per evitare errori futuri. Configuriamo il logging per scrivere in un file:
logging.basicConfig(filename='app.log', filemode='w', level=logging.INFO)
# Adesso tutti i log verranno salvati in app.log
logging.info("Avvio della registrazione dei log nel file.")
Analisi dei log
Analizza i tuoi log per identificare errori frequenti o problemi di performance. Forse il tuo script si imbatte in problemi solo in determinati giorni o ore, e questo può essere notato solo con un'analisi dettagliata dei log. Questa analisi — il tuo detective personale — ti aiuta a capire meglio come funziona la tua applicazione.
GO TO FULL VERSION