1. Logowanie
Dziś zagłębimy się w temat, który może oszczędzić Ci sporo nerwów i cennego czasu — logowanie i obsługa błędów. Nawet najbardziej doświadczony programista nie jest wolny od błędów, a Twoim zadaniem jest uczynić te błędy przewidywalnymi i zarządzalnymi. Wyobraź sobie, że jesteś archeologiem na wykopaliskach, a Twoim zadaniem jest chronić swoją ekspedycję przed niespodziewanymi zawaleniami i zdradliwymi pułapkami — a logowanie i obsługa błędów to Twój wierny kompas i tarcza w tym ryzykownym przedsięwzięciu!
Kiedy mówimy o logowaniu w programowaniu, mamy na myśli proces zapisywania informacji o działaniu programu. To procesy, które zachodzą wewnątrz Twojego kodu i mogą być niewidoczne na pierwszy rzut oka. Zapisując logi, zostawiasz sobie wskazówki, jak Jaś i Małgosia zostawiali okruszki chleba w lesie, aby wrócić do domu.
Instalacja i konfiguracja logowania
Zacznijmy od podstawowych narzędzi w Pythonie. Do logowania będziemy używać wbudowanego modułu logging. To Twój szwajcarski scyzoryk do zapisywania informacji o przebiegu programu.
import logging
# Konfiguracja logowania
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Przykład użycia
logging.info("Początek pracy skryptu")
logging.error("To jest błąd")
Jakie są poziomy logowania?
- DEBUG: najbardziej szczegółowe informacje, zwykle interesujące tylko podczas diagnozowania problemów.
- INFO: potwierdza, że procesy działają zgodnie z oczekiwaniami.
- WARNING: wskazuje na coś niespodziewanego i potencjalnie problematycznego, ale program nadal działa.
- ERROR: tylko poważne błędy, które spowodowały awarię funkcji.
Możesz dostosować poziom logowania, aby filtrować informacje. Na przykład, jeśli interesują Cię tylko błędy i ostrzeżenia, ustaw poziom logging.WARNING.
Przykład logowania w Selenium
Spójrzmy, jak logowanie może być zastosowane w projekcie z Selenium:
from selenium import webdriver
# Konfiguracja logowania
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
try:
logging.info("Inicjalizacja sterownika Chrome")
driver = webdriver.Chrome()
logging.info("Otwarcie strony Python.org")
driver.get("https://www.python.org")
logging.info("Pomyślne zakończenie pracy")
except Exception as e:
logging.error(f"Wystąpił błąd: {e}")
finally:
driver.quit()
Ten przykład pokazuje, jak zintegrować logowanie ze swoim skryptem Selenium, aby monitorować jego działanie. Używamy try, except i finally do obsługi błędów — o tym więcej poniżej.
2. Obsługa błędów w Selenium
W programowaniu, tak jak w życiu, błędy są nieuniknione. Jednak możemy kontrolować, jak na nie reagujemy. Używanie try, except, else i finally pozwala elegancko przechwytywać i obsługiwać błędy.
Przypomnienie o wyjątkach
Przypomnijmy, jak działa obsługa wyjątków:
try:
# Kod, który może wywołać wyjątek
result = 10 / 0
except ZeroDivisionError as e:
# Kod, który zostanie wykonany, jeśli wystąpił wyjątek ZeroDivisionError
logging.error("Dzielenie przez zero jest niemożliwe!")
else:
# Kod, który zostanie wykonany, jeśli wyjątek nie wystąpił
logging.info("Operacja zakończona pomyślnie")
finally:
# Kod, który zostanie wykonany zawsze
logging.info("Operacje zakończone")
Twój kod w bloku try zostanie wykonany. Jeśli wystąpi błąd typu ZeroDivisionError, kod w bloku except zostanie wykonany, a program się nie zawiesi. Blok else jest używany do wykonania kodu, jeśli błąd nie został wywołany. I wreszcie, blok finally jest wykonywany zawsze, niezależnie od tego, czy wystąpił błąd.
Obsługa błędów w Selenium
Selenium oferuje szereg wbudowanych wyjątków do obsługi różnych sytuacji. Oto kilka przydatnych wyjątków i jak je wykorzystać.
-
NoSuchElementException— występuje, gdy element nie zostanie znaleziony. Użyj go do sprawdzania dostępności elementów.Pythontry: element = driver.find_element(By.ID, "element_id") except NoSuchElementException: logging.warning("Element z ID 'element_id' nie został znaleziony.") -
TimeoutException— występuje, jeśli oczekiwany element nie pojawi się na stronie w ustalonym czasie. Służy do zarządzania oczekiwaniami.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("Oczekiwanie na element z ID 'element_id' zakończyło się błędem.") -
ElementClickInterceptedException— występuje, gdy element jest zablokowany przez inny element i kliknięcie jest niemożliwe. Przydatne przy kliku na elementy, które mogą być zakryte przez wyskakujące okna.Pythonfrom selenium.common.exceptions import ElementClickInterceptedException try: driver.find_element(By.ID, "button_id").click() except ElementClickInterceptedException: logging.warning("Element jest zablokowany przez inny element i nie można go kliknąć.")
Ponowne próby i logika odzyskiwania
Aby zwiększyć odporność swojego skryptu, możesz zaimplementować mechanizm ponownych prób w przypadku wystąpienia błędów. Na przykład, jeśli strona jest tymczasowo niedostępna lub element nie został znaleziony, skrypt może spróbować wykonać działanie kilka razy, zanim zakończy pracę z błędem.
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 znaleziony: {value}")
return element
except NoSuchElementException:
attempt += 1
logging.warning(f"Próba {attempt} nieudana, ponowienie za 2 sekundy...")
time.sleep(2)
logging.error(f"Element nie został znaleziony po {retries} próbach.")
return None
Wskazówki dotyczące odporności i niezawodności skryptów
- Używaj jawnych oczekiwań: Skonfiguruj jawne oczekiwania dla elementów, które nie pojawiają się od razu. To zmniejszy liczbę błędów spowodowanych opóźnieniami w ładowaniu.
- Implementuj bloki try-except na każdym etapie: To pozwoli logować błędy i unikać przerwania skryptu w przypadku drobnych usterek.
- Wprowadź ponowne próby dla kluczowych etapów: Jeśli błąd może być tymczasowy, skonfiguruj ponowne próby z kilkusekundowym odstępem.
- Loguj każdy krok: Logowanie każdego kluczowego etapu pomaga analizować przebieg skryptu i wychwytywać ukryte błędy.
- Skonfiguruj powiadomienia o krytycznych błędach: Na przykład możesz wysłać e-mail lub wiadomość na czacie, jeśli w logach zarejestrowany został błąd na poziomie CRITICAL.
3. Prowadź logi z pożytkiem
Teraz, gdy nauczyliśmy się logować i obsługiwać błędy, zróbmy jeszcze jeden krok i zobaczmy, jak maksymalnie wykorzystać logi.
Wybór miejsca i formatu logów
Używaj plików do przechowywania logów, jeśli chcesz je zachować do analizy. To jak prowadzenie dziennika, który możesz przeglądać i analizować, aby unikać przyszłych błędów. Skonfigurujmy logowanie do zapisu w pliku:
logging.basicConfig(filename='app.log', filemode='w', level=logging.INFO)
# Teraz wszystkie logi będą zapisywane w app.log
logging.info("Rozpoczęto zapisywanie logów do pliku.")
Analiza logów
Analizuj swoje logi, aby zidentyfikować często występujące błędy lub problemy z wydajnością. Możliwe, że Twój skrypt napotyka trudności tylko w określone dni lub godziny, i można to zauważyć tylko przy szczegółowym badaniu logów. Ta analiza to Twój osobisty proces detektywistyczny, który pozwala lepiej zrozumieć, jak działa Twoja aplikacja.
GO TO FULL VERSION