1. Leistungsanalyse
Warum ist Optimierung wichtig?
Stell dir ein leistungsstarkes Auto vor, das in drei Sekunden auf 100 km/h beschleunigt, aber so viel Benzin wie ein Wal – Plankton – schluckt. Dein Skript kann genauso schnell, aber extrem "hungrig" sein, wenn es um Ressourcen und Ausführungszeit geht. Mehr noch, Ressourcenausfälle können es instabil machen, was wiederum zu Fehlern führen kann. Optimierung hilft, solche Probleme zu vermeiden.
Zuerst machen wir, wie Chirurgen sagen, einen "Schnitt". Analysieren wir die Leistung unseres Skripts, um herauszufinden, wo es "leidet".
Methoden zur Überprüfung der Geschwindigkeit und Stabilität der Skriptausführung
Eine der einfachen Möglichkeiten zur Analyse ist die Verwendung der grundlegenden Python-Werkzeuge, wie dem Modul time
. Fügen wir ein paar Zeilen in unser Skript ein, um zu verstehen, welche Operationen die meiste Zeit in Anspruch nehmen.
import time
start_time = time.time()
# Hier kommt dein Code für Aktionen mit Selenium
end_time = time.time()
print(f"Ausführungszeit: {end_time - start_time} Sekunden")
Dieses kleine Code-Snippet hilft dir zu bestimmen, wie viel Zeit die Ausführung eines Codeabschnitts benötigt. Mit solchen "Timern" kannst du Engpässe lokalisieren.
Schwachstellen identifizieren und optimieren
Sobald du den Codeabschnitt gefunden hast, der Zeit "frisst", kannst du Maßnahmen ergreifen. Vielleicht greifst du öfter als nötig auf dynamische Elemente zu, oder dein Code ist zu einem "Spaghetti"-Code geworden. Der erste Schritt ist die Identifikation, der zweite das Handeln.
Reduzierung der Anzahl von Anfragen: Überprüfe, ob du zu viele unnötige Seitensprünge oder DOM-Aktualisierungen machst. Zum Beispiel hilft die Verwendung der Methode WebDriverWait
, das Skript erst nach dem vollständigen Laden der gewünschten Elemente auszuführen.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, 'myDynamicElement'))
)
Daten-Caching: Wenn du wiederholt mit denselben Daten arbeitest, überlege dir, diese zwischenzuspeichern. Speichere Daten in Variablen oder im Cache, um ressourcenintensive Operationen zu minimieren.
2. Verbesserung der Skriptstruktur
Wenn dein Code so lesbar ist wie ein U-Bahn-Plan ohne Wegweiser oder Stationsnamen, ist es Zeit, ihn zu verbessern. Eine optimale Code-Struktur ist der Schlüssel zu leichter Verständlichkeit und damit zu Fehlerresistenz.
Verwendung von Daten-Pipelines und optimalen algorithmischen Lösungen
Überlege dir, deinen Code in Form von Pipelines zu strukturieren, bei denen jede Funktion oder jedes Modul für einen Teil der Logik verantwortlich ist. Die Unterteilung des Codes in logische Blöcke verbessert nicht nur die Lesbarkeit, sondern erleichtert auch das Debugging.
def load_page(url):
driver.get(url)
def extract_data():
# Code zur Extraktion von Daten
pass
def save_data():
# Code zum Speichern von Daten
pass
load_page("http://example.com")
extract_data()
save_data()
Verbesserung der Lesbarkeit und Testbarkeit des Codes
Befolge das Prinzip "eine Funktion – eine Aufgabe". Das erleichtert das Testen und das Refactoring. Verwende benannte Konstanten anstelle von "magischen Zahlen" und Zeichenfolgen für mehr Klarheit.
MAX_RETRIES = 5
def fetch_data_with_retry():
for attempt in range(MAX_RETRIES):
try:
# Versuch, Daten abzurufen
pass
except Exception as e:
print(f"Versuch {attempt+1} fehlgeschlagen: {e}")
3. Wenn der Code verbessert werden kann, sollte er verbessert werden
Verwende explizite statt impliziter Wartezeiten
Explizite Wartezeiten ermöglichen eine genaue Steuerung, wann Selenium Aktionen ausführt, nachdem die gewünschten Elemente geladen wurden. Anstatt sich auf implizite Wartezeiten (z. B. implicitly_wait
) zu verlassen, verwende die Bibliothek WebDriverWait
, die es ermöglicht, die Wartezeit für bestimmte Elemente auf Grundlage von Bedingungen anzupassen (z. B. Element sichtbar, für Klicks verfügbar usw.).
Beispiel für die Verwendung einer expliziten Wartezeit
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "target_element"))
)
Vergewissere dich, dass die Seite bereit ist
Nach dem Laden der Seite sind nicht immer sofort alle Elemente verfügbar, insbesondere wenn die Website asynchrone Methoden zum Laden von Inhalten (AJAX) verwendet. Verwende document.readyState
, um die vollständige Dokumentenladung vor der Interaktion zu überprüfen.
Beispiel für die Überprüfung der vollständigen Seitenladung
def wait_for_page_load(driver):
WebDriverWait(driver, 10).until(
lambda d: d.execute_script("return document.readyState") == "complete"
)
Minimiere die Verwendung von time.sleep
Die Methode time.sleep()
zwingt das Skript dazu, eine feste Zeitspanne zu warten und verlangsamt seine Ausführung, insbesondere bei langen Verzögerungen. Stattdessen verwende WebDriverWait
, das flexibler ist und die Wartezeit beendet, sobald die gewünschte Bedingung erfüllt ist.
Verwende robuste Pfade zu Elementen
Fragile Lokatoren wie XPath-Pfade, die von bestimmten HTML-Strukturen abhängen, können schnell ausfallen, wenn sich die Struktur der Website ändert. Um dies zu vermeiden, versuche, robustere Lokatoren wie Attribute id
, name
, class
und data-*
zu verwenden, die stabiler sind.
Beispiel für die zuverlässige Verwendung von Attributen
# Verwende id, wenn verfügbar
element = driver.find_element(By.ID, "submit_button")
# Wenn kein id vorhanden ist, verwende data-* oder eindeutige Klassen
element = driver.find_element(By.CSS_SELECTOR, "[data-role='main-button']")
Schließe Pop-ups und Banner
Einige Websites enthalten Pop-ups, die die Skriptausführung behindern. Die Behandlung solcher Elemente ermöglicht es, Blockierungen von Basisaktionen zu vermeiden.
Beispiel zum Schließen eines Pop-ups
from selenium.common.exceptions import ElementClickInterceptedException
try:
close_popup = driver.find_element(By.CLASS_NAME, "popup-close-button")
close_popup.click()
except (NoSuchElementException, ElementClickInterceptedException):
pass # Ignoriere, wenn Element nicht gefunden oder Schließen nicht möglich ist
Konfiguriere die Protokollierung
Logging hilft, die Aktionen des Skripts zu verfolgen und Fehler in der Arbeit zu erkennen. Verwende das integrierte Modul logging
, um jeden wichtigen Schritt des Skripts zu protokollieren, was die Fehlersuche und Analyse erleichtert.
Beispiel zur Konfiguration des Loggings
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logging.info("Skript gestartet")
logging.warning("Element nicht gefunden, weiter mit der Arbeit")
logging.error("Fehler aufgetreten")
4. Typische Fehler von Anfängern
Vergiss nicht, Web-Treiber und Bibliotheken zu aktualisieren. Dies hilft, Inkompatibilitäten und Fehler zu vermeiden, die durch Browser-Updates und Änderungen in der Selenium-API entstehen.
Und zum Schluss: Wenn dein Skript häufig "abstürzt", ohne dass ein klarer Grund erkennbar ist, blockiert dein Testserver möglicherweise wiederholte Anfragen. Überprüfe, ob du die Zugriffsregeln verletzst, und denke über die Verwendung von Proxyservern oder die Anpassung der Anfragehäufigkeit nach.
Die Optimierung von Skripten ist nicht nur eine technische Aufgabe, sondern eine Kunst, die mit der Erfahrung kommt. Ich hoffe, die heutigen Tipps helfen dir, zuverlässige und stabile Skripte zu erstellen, die jeder Belastung standhalten.
GO TO FULL VERSION