1. Gestione degli errori negli script
Problemi del web scraping
Immagina: il tuo script è lì tutto bello e pronto per lavorare, ma all'improvviso scivola su una buccia di banana — e crash! Errori e fallimenti. Come fare in modo che sopravviva nelle dure condizioni di Internet? Oggi insegneremo al tuo script due abilità fondamentali: la resilienza e il tentativo di nuovo. Sì sì, configureremo retry e timeout.
Lavorare con il web scraping può essere magnifico fino al momento in cui scopri che il tuo script si è spento improvvisamente a causa di:
- Errori di connessione.
- Server temporaneamente non disponibili.
- Cambiamenti imprevedibili nella struttura HTML delle pagine.
Il tuo script, come un Jedi, deve essere pronto agli imprevisti e saper affrontarli. A volte i problemi possono essere risolti semplicemente aspettando un minuto e riprovando la richiesta. Ed è qui che entrano in scena i nostri eroi: retry e timeout!
Introduzione ai meccanismi di gestione degli errori
Per iniziare, ricordiamo le basi: la gestione degli errori in Python. Utilizziamo i blocchi try-except
per gestire gli errori e impedire loro di interrompere il funzionamento del nostro script.
import requests
try:
response = requests.get('https://example.com')
response.raise_for_status() # verifica del successo della richiesta
except requests.exceptions.RequestException as e:
print(f'E\' avvenuto un errore: {e}')
2. Configurazione dei retry
Perché utilizzare i tentativi?
Uno script che si arrende al primo errore è come un gatto che ha paura della pioggia. Ma tu hai bisogno di uno script che resista stoicamente a qualche inconveniente. Ed è per questo che configuriamo i retry — affinché il tuo script diventi sicuro di sé.
Come configurare i retry
Ora vediamo come possiamo organizzare i retry. Uno dei modi più semplici è utilizzare la libreria urllib3
, che offre funzionalità per inviare automaticamente di nuovo le richieste in caso di errori.
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
try:
response = session.get('https://example.com')
response.raise_for_status()
print(response.content)
except requests.exceptions.RequestException as e:
print(f'E\' avvenuto un errore: {e}')
In questo esempio, abbiamo creato una session
a cui abbiamo applicato il meccanismo di retry (Retry
). Abbiamo indicato che devono essere fatti fino a 5 tentativi in caso di errori con i codici 500, 502, 503 e 504. backoff_factor=1
significa che il tempo tra i tentativi aumenterà seguendo il principio della crescita esponenziale (1, 2, 4, 8... secondi).
3. Timeout: prevenire il blocco
Impostare il limite di attesa
I timeout sono come una sveglia: ti aiutano a non rimanere bloccato in attesa della risposta del server. Impostando un timeout, dici al tuo script: "Basta aspettare! Se il server non risponde entro il tempo stabilito, vai avanti!"
try:
response = requests.get('https://example.com', timeout=10)
response.raise_for_status()
print(response.content)
except requests.exceptions.Timeout:
print('La richiesta ha superato il tempo di attesa')
except requests.exceptions.RequestException as e:
print(f'E\' avvenuto un errore: {e}')
Perché è importante?
Ti è mai capitato di restare congelato in attesa che il tuo script ricevesse una risposta da un server ormai fuori uso? I timeout prevengono inutili attese e permettono al tuo codice di recuperare rapidamente e continuare a funzionare. Non lasciare che il tuo script "pensi" che possa prendersi pause infinite!
4. Esempi di configurazione
Realizzare uno script resiliente con retry
Ora combiniamo il nostro script, che sarà resiliente come l'armatura di Iron Man. Utilizzeremo sia i timeout che i retry.
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import requests
def fetch_url(url):
session = requests.Session()
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retries))
try:
response = session.get(url, timeout=10)
response.raise_for_status()
return response.content
except requests.exceptions.Timeout:
print('La richiesta ha superato il tempo di attesa')
except requests.exceptions.RequestException as e:
print(f'E\' avvenuto un errore: {e}')
return None
content = fetch_url('https://example.com')
if content:
print('Dati scaricati con successo!')
Utilizzare i timeout per evitare il blocco dello script
Abbiamo già mostrato come impostare i timeout. Ora assicuriamoci che il nostro script non solo sia resiliente, ma che reagisca in modo intelligente alle attese prolungate. Invece di "bloccarsi", semplicemente farà notare al proprietario: "Ehi, il server ci mette troppo, non aspetterò più!"
Questo approccio semplice e conciso renderà il tuo codice affidabile e pronto a combattere le varie situazioni imprevedibili che possono verificarsi su Internet.
Applicazione pratica
Quando sviluppi progetti reali di scraping, ti troverai spesso a fare i conti con diverse limitazioni imposte dai server. I retry e i timeout sono i tuoi migliori alleati per ridurre il rischio di errori. Questo ti aiuterà a garantire il funzionamento continuo del tuo codice, soprattutto quando si tratta di elaborazione automatizzata dei dati e nei casi in cui è fondamentale ottenere risultati precisi in tempo. Queste tecniche possono anche migliorare la qualità del tuo curriculum e il livello di fiducia dei clienti a cui fornisci i dati.
GO TO FULL VERSION