CodeGym /Kurse /Python SELF DE /Fehlerbehandlung beim Web-Scraping

Fehlerbehandlung beim Web-Scraping

Python SELF DE
Level 32 , Lektion 4
Verfügbar

Wenn du es bis zu dieser Vorlesung geschafft hast, hast du wahrscheinlich schon ein gutes Verständnis davon, wie Web-Scraping funktioniert und wie man das großartige BeautifulSoup verwendet, um benötigte Daten aus HTML zu extrahieren. Doch in der Welt des Web-Scrapings ist nicht alles so reibungslos, wie in Lehrbüchern beschrieben. Manchmal verwandelt sich unser Traum, Daten zu sammeln, in das Bekämpfen von Fehlern. Lass uns also darüber sprechen, wie wir diese Stolpersteine umgehen und unseren Scraper so robust wie möglich machen können.

1. Häufige Fehler beim Web-Scraping

Fehler 404 und andere HTTP-Fehler

Ein klassisches Problem: Du versuchst, eine Seite zu bekommen, und anstelle von Inhalten erhältst du ein stolzes "404 Not Found". Dies kann passieren, weil die Seite gelöscht oder verschoben wurde. Andere häufige HTTP-Fehler sind 403 (Forbidden), 500 (Internal Server Error) und 503 (Service Unavailable).

Änderung der HTML-Struktur

Du hast Stunden damit verbracht, Code zu schreiben, um Daten zu extrahieren, und am nächsten Tag beschließt die Website, sich "aufzuhübschen" und ändert die HTML-Struktur. Oh nein, alles muss wieder neu geschrieben werden!

Beschränkungen für Anfragen

Einige Websites werden misstrauisch, wenn sie den ganzen Tag von Web-Scrapern "abgeleckt" werden. Im besten Fall wirst du für eine Weile blockiert, im schlimmsten Fall für immer.

Wartezeiten und Timeouts

Manchmal laden Seiten langsam, und dein Skript kann abstürzen, wenn die Wartezeit die Standard-Timeout-Zeit überschreitet.

2. Methoden zur Fehlerbehandlung

Verwendung von try-except

Deine Skripte sollten nicht bei jeder Überraschung abstürzen. Das Hinzufügen von try-except-Blöcken hilft, Fehler abzufangen und deinen Web-Scraper am Laufen zu halten, als wäre nichts passiert.

Python

    import requests
    from bs4 import BeautifulSoup
    
    url = 'http://example.com/some-nonexistent-page'
    
    try:
        response = requests.get(url)
        response.raise_for_status()  # Ruft HTTPError für schlechte Antworten auf
    except requests.exceptions.HTTPError as errh:
        print("HTTP-Fehler:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Verbindungsfehler:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout-Fehler:", errt)
    except requests.exceptions.RequestException as err:
        print("OOps: Etwas anderes", err)
        

Ein gutes Skript fängt nicht nur die Ausnahme ab - es reagiert auch auf jeden Fehlertyp. Du wurdest per IP gebannt – wechsle zum nächsten Proxy, die Website ist ausgefallen – parse währenddessen eine andere. Wenn auf der Seite erwartete Elemente nicht gefunden werden, kannst du den Besitzer des Parsers benachrichtigen, dass das Parsing-Skript aktualisiert werden muss, und ihm eine E-Mail senden.

Logging

"Warum Logs?" — fragst du dich. Weil Logs deine zweite Sicht sind. Sie helfen dir, herauszufinden, was schiefgelaufen ist, und den Fehler so schnell wie möglich zu beheben.

Python

import logging

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

try:
    # Dein Scraping-Code
    pass
except Exception as e:
    logging.error("Ein Fehler ist aufgetreten", exc_info=True)
    

Verwendung von Timeouts und Retries

Manchmal brauchst du nur ein wenig Geduld und musst es erneut versuchen. Für diese Zwecke eignen sich Timeouts und Retries hervorragend.

Python

try:
    response = requests.get(url, timeout=5)
    response.raise_for_status()
except requests.exceptions.Timeout:
    print("Timeout ist aufgetreten. Neuer Versuch...")
    # Wiederhole die Anfrage oder führe eine andere Aktion aus
    

3. Beispiele für robustes Scraping

Ein einfacher Scraper mit Fehlerbehandlung

Lass uns einen kleinen, aber zuverlässigen Scraper erstellen, der einige häufige Fehler behandeln kann.

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("HTTP-Fehler: %s", errh)
    except requests.exceptions.ConnectionError as errc:
        logging.error("Verbindungsfehler: %s", errc)
    except requests.exceptions.Timeout as errt:
        logging.warning("Timeout ist aufgetreten. Neuer Versuch...")
        time.sleep(1)  # Warte kurz und probiere es erneut
        return fetch_html(url)
    except requests.exceptions.RequestException as err:
        logging.error("OOps: Etwas anderes %s", err)
    return None

html_content = fetch_html(url)
if html_content:
    soup = BeautifulSoup(html_content, 'html.parser')
    # Dein Code zum Extrahieren von Daten
else:
    print("Die Seite konnte nicht abgerufen werden.")
    

Speichern von Daten in Teilen

Um bereits extrahierte Daten im Fehlerfall nicht zu verlieren, speichere sie in Teilen. Wenn du zum Beispiel Informationen aus einer Liste von Seiten extrahierst und die Ergebnisse stückweise speicherst, minimierst du das Risiko eines Datenverlusts.

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)
    

Auf diese Weise verlierst du nicht alle Daten, wenn dein Skript mitten in der Arbeit abstürzt, und kannst dort weitermachen, wo du aufgehört hast.

Die Seite, die du scrapest, kann sich teilweise ändern, und der Großteil der Daten bleibt weiterhin verfügbar. Es wäre schade, das Scraping abzubrechen und wertvolle Daten zu verlieren, wenn nur ein kleiner Prozentsatz davon fehlt.

1
Umfrage/Quiz
Datenextraktion, Level 32, Lektion 4
Nicht verfügbar
Datenextraktion
Datenextraktion
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION