CodeGym /Corso Java /Python SELF IT /Gestione degli errori nel web scraping

Gestione degli errori nel web scraping

Python SELF IT
Livello 32 , Lezione 4
Disponibile

Se sei arrivato a questa lezione, significa che hai già una buona idea di come funziona il web scraping e come utilizzare il fantastico BeautifulSoup per estrarre i dati HTML di cui hai bisogno. Tuttavia, nel mondo del web scraping, non è tutto rose e fiori come si legge nei libri di testo. A volte, il nostro sogno di estrarre dati si trasforma in una lotta contro gli errori, quindi parliamo di come evitare ostacoli e rendere il nostro scraper il più stabile possibile.

1. Errori comuni nel web scraping

Errore 404 e altri errori HTTP

Un classico problema: provi a ottenere una pagina e invece del contenuto ricevi un orgoglioso "404 Not Found". Questo può succedere perché la pagina è stata rimossa o spostata. Altri errori HTTP comuni includono 403 (Forbidden), 500 (Internal Server Error) e 503 (Service Unavailable).

Modifica della struttura HTML

Hai passato un sacco di tempo a scrivere il codice per estrarre i dati e il giorno dopo il sito decide di "rifarsi il look" e cambia la struttura HTML. Eh sì, tocca riscrivere tutto da capo!

Limitazioni sul numero di richieste

Alcuni siti iniziano a sospettare qualcosa di strano quando sono bersagliati tutto il giorno da scraper. Nel migliore dei casi, ti bloccheranno per un po', nel peggiore — per sempre.

Tempi di attesa e timeout

A volte le pagine si caricano lentamente e il tuo script può andare in crash se l'attesa supera il tempo di timeout standard.

2. Metodi per la gestione degli errori

Uso di try-except

I tuoi script non dovrebbero bloccarsi per ogni imprevisto. L'aggiunta di blocchi try-except aiuta a gestire gli errori e a fare in modo che il tuo scraper continui a funzionare come se nulla fosse successo.

Python

    import requests
    from bs4 import BeautifulSoup
    
    url = 'http://example.com/some-nonexistent-page'
    
    try:
        response = requests.get(url)
        response.raise_for_status()  # Lancia HTTPError per risposte errate
    except requests.exceptions.HTTPError as errh:
        print("Errore HTTP:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Errore di Connessione:", errc)
    except requests.exceptions.Timeout as errt:
        print("Errore di Timeout:", errt)
    except requests.exceptions.RequestException as err:
        print("OOps: Qualcos'altro è andato storto", err)
        

Uno script ben fatto non si limita a intercettare le eccezioni — ha una risposta per ogni tipo di errore. Sei stato bannato per IP? Passa al prossimo proxy. Il sito è caduto? Intanto analizza un altro. Se non vengono trovati alcuni elementi nella pagina che dovrebbero esserci, puoi avvisare il proprietario dello scraper che il codice deve essere aggiornato e inviargli un'email.

Logging

"A cosa servono i log?" — potresti chiederti. Beh, i log sono come avere una seconda vista. Ti aiutano a capire cosa è andato storto e a risolvere il problema il più rapidamente possibile.

Python

import logging

logging.basicConfig(filename='scraper.log', level=logging.INFO)

try:
    # Il tuo codice di scraping
    pass
except Exception as e:
    logging.error("Si è verificata un'eccezione", exc_info=True)
    

Uso di timeout e retry

A volte tutto ciò che serve è aspettare un po' e riprovare. A questo scopo, i timeout e i retry sono perfetti.

Python

try:
    response = requests.get(url, timeout=5)
    response.raise_for_status()
except requests.exceptions.Timeout:
    print("Timeout rilevato. Riprovo...")
    # Ripeti la richiesta o esegui un'altra azione
    

3. Esempi di scraping resiliente

Uno scraper semplice con gestione degli errori

Creiamo un piccolo, ma affidabile scraper che può gestire alcuni errori comuni.

Python

import requests
from bs4 import BeautifulSoup
import time
import logging

logging.basicConfig(filename='scraper.log', level=logging.INFO)

url = 'http://example.com/some-nonexistent-page'

def fetch_html(url):
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()
        return response.text
    except requests.exceptions.HTTPError as errh:
        logging.error("Errore HTTP: %s", errh)
    except requests.exceptions.ConnectionError as errc:
        logging.error("Errore di Connessione: %s", errc)
    except requests.exceptions.Timeout as errt:
        logging.warning("Timeout rilevato. Riprovo...")
        time.sleep(1)  # Aspetta un po' e riprova
        return fetch_html(url)
    except requests.exceptions.RequestException as err:
        logging.error("OOps: Qualcos'altro è andato storto %s", err)
    return None

html_content = fetch_html(url)
if html_content:
    soup = BeautifulSoup(html_content, 'html.parser')
    # Il tuo codice per estrarre i dati
else:
    print("Impossibile recuperare il contenuto della pagina.")
    

Salvataggio dei dati a pezzi

Per non perdere i dati già estratti in caso di crash, salva i dati a pezzi. Ad esempio, se stai estraendo informazioni da un elenco di pagine, salvando i risultati man mano che procedi, minimizzi il rischio di perdere dati.

Python

import csv

def save_to_csv(data, filename='data.csv'):
    with open(filename, mode='a', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(data)
    

In questo modo, anche se il tuo script si blocca a metà, non perderai tutti i dati e potrai continuare dallo stato salvato più recente.

La pagina che stai analizzando potrebbe cambiare parzialmente e la maggior parte dei dati sarà ancora disponibile. Non sarebbe bello annullare lo scraping e perdere dati preziosi se manca solo una piccola percentuale di essi.

1
Опрос
Estrazione dati,  32 уровень,  4 лекция
недоступен
Estrazione dati
Estrazione dati
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION