CodeGym /Corsi /Python SELF IT /Ottimizzazione dello script per un funzionamento stabile ...

Ottimizzazione dello script per un funzionamento stabile e per ridurre al minimo gli errori

Python SELF IT
Livello 38 , Lezione 3
Disponibile

1. Analisi delle prestazioni

A cosa serve l'ottimizzazione?

Immagina una macchina potente che può accelerare fino a 100 km/h in tre secondi, ma che consuma benzina come una balena che mangia plancton. Lo stesso accade con il tuo script, che potrebbe essere molto veloce, ma estremamente "affamato" di risorse e tempo di esecuzione. Inoltre, "perdite" di risorse potrebbero renderlo instabile, portando a errori. L'ottimizzazione ti aiuta a evitare questi problemi.

Per prima cosa, come dicono i chirurghi, facciamo un "taglio". Facciamo un'analisi delle prestazioni del nostro script per capire dove potrebbe "soffrire".

Metodi per controllare velocità e stabilità di esecuzione dello script

Uno dei metodi più semplici di analisi è utilizzare gli strumenti base di Python, come il modulo time. Aggiungiamo qualche riga al nostro script per capire quali operazioni richiedono più tempo.

Python

import time

start_time = time.time()
# Qui va il tuo codice per eseguire azioni con Selenium
end_time = time.time()

print(f"Tempo di esecuzione: {end_time - start_time} secondi")
  

Questo piccolo frammento di codice ti aiuterà a determinare quanto tempo impiega una parte del codice. Usando questi "timer", puoi localizzare i "colli di bottiglia".

Identificazione dei punti deboli e loro ottimizzazione

Una volta trovato il pezzo di codice che "mangia" tempo, puoi agire. Forse accedi agli elementi dinamici più spesso del necessario oppure il tuo codice è diventato simile a degli "spaghetti". Il primo passo è l'identificazione, il secondo è l'azione.

Riduzione del numero di richieste: Controlla se non stai facendo troppi passaggi inutili tra pagine o aggiornamenti del DOM. Ad esempio, l'uso del metodo WebDriverWait aiuta a eseguire lo script solo dopo il caricamento completo degli elementi desiderati.

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, 'myDynamicElement'))
)
  

Caching dei dati: Se lavori spesso con gli stessi dati, pensa al caching. Conserva i dati nelle variabili o in una cache per ridurre al minimo le operazioni costose in termini di risorse.

2. Migliorare la struttura dello script

Se il tuo codice è leggibile come una mappa della metropolitana senza indicazioni e nomi delle stazioni, è il momento di migliorarlo. Una struttura ottimale del codice è la chiave per una facile comprensione e, quindi, per una maggior resistenza agli errori.

Uso di pipeline di dati e soluzioni algoritmiche ottimali

Pensa a organizzare il tuo codice come una pipeline, dove ogni funzione o modulo si occupa di una parte specifica della logica. Dividere il codice in blocchi logici non solo migliora la leggibilità, ma facilita anche il debug.

Python

def load_page(url):
    driver.get(url)

def extract_data():
    # Codice per estrarre dati
    pass

def save_data():
    # Codice per salvare dati
    pass

load_page("http://example.com")
extract_data()
save_data()
  

Miglioramento della leggibilità e testabilità del codice

Segui il principio "una funzione — un compito". Questo semplifica il testing e il refactoring. Usa costanti nominate invece di numeri o stringhe "magiche" per una maggiore chiarezza.

Python

MAX_RETRIES = 5

def fetch_data_with_retry():
    for attempt in range(MAX_RETRIES):
        try:
            # Tentativo di richiesta dati
            pass
        except Exception as e:
            print(f"Tentativo {attempt+1} fallito: {e}")
  

3. Se il codice può essere migliorato, deve esserlo

Usa attese esplicite invece di implicite

Le attese esplicite consentono di controllare esattamente quando Selenium esegue un'azione, attendendo la disponibilità degli elementi necessari. Invece di fare affidamento su attese implicite (ad esempio, implicitly_wait), usa la libreria WebDriverWait, che ti permette di impostare attese per elementi specifici in base a determinate condizioni (ad esempio, l'elemento è visibile, cliccabile, ecc.).

Esempio di utilizzo di attese esplicite

Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "target_element"))
)
  

Assicurati che la pagina sia pronta

Dopo il caricamento della pagina, gli elementi potrebbero non essere immediatamente disponibili, soprattutto se il sito utilizza metodi di caricamento asincrono (AJAX). Usa document.readyState per verificare che il documento sia completamente caricato prima di iniziare l'interazione.

Esempio di verifica del caricamento completo della pagina

Python

def wait_for_page_load(driver):
    WebDriverWait(driver, 10).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
  

Minimizza l'uso di time.sleep

Il metodo time.sleep() costringe lo script ad aspettare un tempo fisso e rallenta il suo funzionamento, specialmente con lunghe attese. Usa invece WebDriverWait, che è più flessibile e termina l'attesa non appena la condizione desiderata è soddisfatta.

Usa percorsi stabili per gli elementi

I locator fragili, come i percorsi XPath che dipendono da specifiche strutture HTML, potrebbero non funzionare più se la struttura del sito cambia. Per evitarlo, prova a usare locator più stabili, come gli attributi id, name, class e data-*, che sono più affidabili.

Esempio di utilizzo affidabile degli attributi

Python

# Usa id per cercare, se disponibile
element = driver.find_element(By.ID, "submit_button")

# Se non c'è id, puoi usare l'attributo data-* o classi uniche
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
  

Chiudi popup e banner

Alcuni siti contengono popup che interferiscono con l'esecuzione dello script. Gestire questi elementi ti permette di evitare blocchi delle azioni principali.

Esempio di chiusura di un popup

Python

from selenium.common.exceptions import ElementClickInterceptedException

try:
    close_popup = driver.find_element(By.CLASS_NAME, "popup-close-button")
    close_popup.click()
except (NoSuchElementException, ElementClickInterceptedException):
    pass  # Ignora se l'elemento non è trovato o impossibile chiudere
  

Configura la gestione del logging

Il logging aiuta a tracciare le azioni dello script e a identificare errori nel funzionamento. Usa il modulo integrato logging per registrare ogni passaggio importante dello script, il che facilita il debug e l'analisi.

Esempio di configurazione del logging

Python

import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

logging.info("Lo script è stato avviato")
logging.warning("Elemento non trovato, procedo con l'esecuzione")
logging.error("Si è verificato un errore")
  

Controlla la visibilità degli elementi prima dell'interazione

A volte gli elementi vengono caricati nella pagina, ma sono invisibili o non sono disponibili per l'interazione. Usa WebDriverWait con la condizione element_to_be_clickable per assicurarti che l'elemento sia disponibile prima di cliccarci sopra o inserire dati.

Python

from selenium.webdriver.support import expected_conditions as EC

element = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.ID, "button_id"))
)
element.click()
  

Gestisci errori di connessione e timeout

Durante lo scraping dei siti web, possono verificarsi errori di connessione o timeout quando il server non risponde. Configura la gestione di questi errori per consentire allo script di saltare o ripetere le azioni in caso di inattività temporanea del sito.

Esempio di gestione degli errori di connessione

Python

from selenium.common.exceptions import TimeoutException

try:
    driver.get("https://example.com")
except TimeoutException:
    logging.error("Impossibile connettersi alla pagina. Passo al prossimo compito.")
  

Chiudi il browser

Per evitare accumuli di risorse e chiudere il browser in caso di errori, utilizza sempre try-finally o strutture simili per terminare correttamente l'esecuzione.

Python

try:
    # Azioni con Selenium
    pass
finally:
    driver.quit()  # Chiusura del browser
  

4. Errori comuni dei principianti

Non dimenticare di aggiornare i web driver e le librerie. Questo ti aiuta a evitare incompatibilità e errori legati agli aggiornamenti del browser e ai cambiamenti nelle API di Selenium.

Infine, se il tuo script spesso "crasha" senza motivo apparente, potrebbe essere che il tuo server di test stia bloccando troppe richieste frequenti. Controlla se stai violando le regole di accesso e considera l'uso di proxy server o l'aggiustamento della frequenza delle richieste.

L'ottimizzazione degli script non è solo una questione tecnica, è un'arte che si acquisisce con l'esperienza. Spero che i consigli di oggi ti aiutino a creare script affidabili e stabili, pronti a gestire qualsiasi carico.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION