1. Logging
Heute tauchen wir in ein Thema ein, das dir möglicherweise einige Nerven und wertvolle Zeit sparen wird – Logging und Fehlerbehandlung. Selbst der erfahrenste Programmierer ist nicht gegen Fehler gefeit, und deine Aufgabe ist es, diese Fehler vorhersehbar und handhabbar zu machen. Stell dir vor, du bist ein Archäologe auf einer Expedition, und deine Aufgabe ist es, deine Gruppe vor unvorhergesehenen Einstürzen und tückischen Fallen zu schützen – Logging und Fehlerbehandlung sind dabei dein treuer Kompass und Schutzschild!
Wenn wir in der Programmierung über Logging sprechen, meinen wir den Prozess des Aufzeichnens von Informationen über den Programmablauf. Es handelt sich um Prozesse, die innerhalb deines Codes ablaufen und auf den ersten Blick vielleicht nicht sichtbar sind. Indem du Logs schreibst, hinterlässt du dir selbst Hinweise, wie Hänsel und Gretel Brotkrümel im Wald, um nach Hause zu finden.
Installation und Konfiguration von Logging
Beginnen wir mit den grundlegenden Werkzeugen in Python. Für
das Logging verwenden wir das integrierte Modul logging
.
Es ist dein Schweizer Taschenmesser zum Aufzeichnen von
Informationen über den Ablauf deines Programms.
import logging
# Logging-Konfiguration
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Beispielverwendung
logging.info("Start des Skripts")
logging.error("Das ist ein Fehler")
Welche Arten von Logging-Leveln gibt es?
- DEBUG: Die detailliertesten Informationen, die normalerweise nur bei der Fehlerdiagnose relevant sind.
- INFO: Bestätigt, dass die Prozesse wie erwartet funktionieren.
- WARNING: Weist auf etwas Unerwartetes und potenziell Problematisches hin, das Programm funktioniert jedoch weiterhin.
- ERROR: Nur schwere Fehler, die dazu führen, dass eine Funktion ausfällt.
Du kannst das Logging-Level anpassen, um Informationen zu
filtern. Wenn dich beispielsweise nur Fehler und
Warnmeldungen interessieren, stelle das Level auf
logging.WARNING
.
Beispiel für Logging in Selenium
Lassen wir uns ansehen, wie Logging in einem Projekt mit Selenium verwendet werden kann:
from selenium import webdriver
# Logging-Konfiguration
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
try:
logging.info("Initialisiere Chrome-Driver")
driver = webdriver.Chrome()
logging.info("Öffne die Seite Python.org")
driver.get("https://www.python.org")
logging.info("Arbeit erfolgreich abgeschlossen")
except Exception as e:
logging.error(f"Ein Fehler ist aufgetreten: {e}")
finally:
driver.quit()
Dieses Beispiel zeigt, wie Logging in dein Selenium-Skript
integriert werden kann, um dessen Ausführung zu verfolgen. Wir
verwenden try
, except
und
finally
zur Fehlerbehandlung – dazu weiter unten
mehr.
2. Fehlerbehandlung bei Selenium
In der Programmierung, wie auch im Leben, sind Fehler
unvermeidlich. Es liegt jedoch an uns zu bestimmen, wie wir
darauf reagieren. Die Verwendung von try
,
except
, else
und finally
erlaubt ein elegantes Erfassen und Behandeln von Fehlern.
Erinnerung an die Arbeit mit Ausnahmen
Lasst uns kurz wiederholen, wie die Fehlerbehandlung funktioniert:
try:
# Code, der eine Ausnahme werfen kann
result = 10 / 0
except ZeroDivisionError as e:
# Code, der ausgeführt wird, wenn eine ZeroDivisionError-Ausnahme auftritt
logging.error("Eine Division durch Null ist nicht möglich!")
else:
# Code, der ausgeführt wird, wenn keine Ausnahme auftritt
logging.info("Operation erfolgreich abgeschlossen")
finally:
# Code, der immer ausgeführt wird
logging.info("Operationen abgeschlossen")
Der Codeblock in try
wird ausgeführt. Wenn ein
Fehler vom Typ ZeroDivisionError
auftritt, wird
der Codeblock in except
ausgeführt und das
Programm stürzt nicht ab. Der Block else
wird
ausgeführt, wenn keine Ausnahme ausgelöst wurde. Schließlich
wird der Block finally
unabhängig davon
ausgeführt, ob ein Fehler aufgetreten ist oder nicht.
Fehlerbehandlung in Selenium
Selenium bietet eine Reihe von eingebauten Ausnahmen zum Behandeln verschiedener Situationen. Hier sind einige nützliche Ausnahmen und deren Verwendung.
-
NoSuchElementException
– tritt auf, wenn ein Element nicht gefunden wird. Verwenden Sie dies, um die Verfügbarkeit von Elementen zu überprüfen.Pythontry: element = driver.find_element(By.ID, "element_id") except NoSuchElementException: logging.warning("Element mit ID 'element_id' wurde nicht gefunden.")
-
TimeoutException
– tritt auf, wenn ein erwartetes Element innerhalb der festgelegten Zeit nicht auf der Seite erscheint. Wird zur Verwaltung von Wartezeiten verwendet.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("Warten auf Element mit ID 'element_id' ist fehlgeschlagen.")
-
ElementClickInterceptedException
– tritt auf, wenn ein Element von einem anderen Element blockiert wird und nicht geklickt werden kann. Nützlich bei Klicks auf Elemente, die durch Pop-ups verdeckt sein könnten.Pythonfrom selenium.common.exceptions import ElementClickInterceptedException try: driver.find_element(By.ID, "button_id").click() except ElementClickInterceptedException: logging.warning("Element wird von einem anderen Element blockiert und kann nicht geklickt werden.")
Wiederholungsversuche und Wiederherstellungslogik
Um die Stabilität deines Skripts zu erhöhen, kannst du einen Mechanismus für Wiederholungsversuche bei Fehlern implementieren. Wenn eine Website z. B. vorübergehend nicht erreichbar ist oder ein Element nicht gefunden wird, kann das Skript versuchen, die Aktion mehrmals auszuführen, bevor es mit einem Fehler abbricht.
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"Element gefunden: {value}")
return element
except NoSuchElementException:
attempt += 1
logging.warning(f"Versuch {attempt} fehlgeschlagen, Wiederholung in 2 Sekunden...")
time.sleep(2)
logging.error(f"Element nach {retries} Versuchen nicht gefunden.")
return None
Tipps zur Skript-Stabilität und Zuverlässigkeit
- Verwende explizite Wartezeiten: Konfiguriere explizite Wartezeiten für Elemente, die nicht sofort erscheinen. Dies reduziert die Fehleranzahl durch Ladeverzögerungen.
- Setze try-except-Blöcke auf jeder Stufe ein: Dies ermöglicht das Logging von Fehlern und verhindert Skriptabbrüche bei geringfügigen Problemen.
- Implementiere Wiederholungsversuche für kritische Schritte: Wenn ein Fehler vorübergehend sein kann, richte Wiederholungsversuche mit mehreren Sekunden Verzögerung ein.
- Logge jeden Schritt: Das Logging jedes wichtigen Schritts hilft, den Programmfluss zu analysieren und versteckte Fehler zu finden.
- Richte Benachrichtigungen bei kritischen Fehlern ein: Beispielsweise kannst du eine E-Mail oder Nachricht in einen Chat senden, wenn ein kritischer Fehler im Log erfasst wird.
3. Logs sinnvoll nutzen
Jetzt, da wir Logging und Fehlerbehandlung beherrschen, gehen wir einen Schritt weiter und sehen uns an, wie wir die Logs am besten nutzen können.
Auswahl des Speicherorts und Formats der Logs
Verwende eine Datei, um Logs zu speichern, wenn du sie für eine spätere Analyse aufbewahren möchtest. Das ist wie das Führen eines Tagebuchs, das du lesen und analysieren kannst, um zukünftige Fehler zu vermeiden. Hier ist die Konfiguration für das Logging in eine Datei:
logging.basicConfig(filename='app.log', filemode='w', level=logging.INFO)
# Jetzt werden alle Logs zur Datei app.log gespeichert
logging.info("Beginne mit der Aufzeichnung von Logs in die Datei.")
Analyse der Logs
Analysiere deine Logs, um häufig auftretende Fehler oder Leistungsprobleme zu erkennen. Vielleicht stößt dein Skript nur zu bestimmten Tagen oder Zeiten auf Probleme, und das kannst du nur durch eine detaillierte Untersuchung der Logs herausfinden. Diese Analyse ist dein persönlicher Detektivprozess, der dir hilft, besser zu verstehen, wie deine Anwendung funktioniert.
GO TO FULL VERSION