Selenium-Wartemechanismen
In Selenium ist der Wartemechanismus entscheidend, um sicherzustellen, dass Seitenelemente geladen sind, bevor Operationen ausgeführt werden.
Da die Ladegeschwindigkeit von Webseiten durch Faktoren wie Netzwerk- und Serverleistung beeinflusst wird, kann der direkte Zugriff auf Elemente, die noch nicht fertig geladen sind, zu Skriptfehlern führen.
Selenium bietet mehrere Wartemechanismen, um dieses Problem zu lösen.
1. Implizites Warten (implicitly_wait)
1.1 Was ist implizites Warten?
Das implizite Warten ist ein globaler Wartemechanismus, der beim Suchen von Elementen eine bestimmte Zeit lang wartet. Wenn das Element innerhalb der angegebenen Zeit gefunden wird, führt Selenium sofort die nachfolgenden Operationen aus; wenn das Element nach dem Timeout immer noch nicht gefunden wird, wird es eine Ausnahme auslösenNoSuchElementExceptioneine Ausnahme.
1.2 Wie verwendet man implizites Warten?
Das implizite Warten wird durch dieimplicitly_wait()Methode festgelegt. Diese Methode muss nur einmal aufgerufen werden, und alle nachfolgenden Element-Suchoperationen folgen dieser Wartezeit.
Beispiel
from selenium.webdriver.chrome.service import Service as ChromeService
# Korrekten Treiberpfad festlegen
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Implizite Wartezeit auf 10 Sekunden setzen
driver.implicitly_wait(10)
# Webseite öffnen
driver.get("https://example.com")
# Element finden
element = driver.find_element_by_id("element_id")
# Den Browser schließen
driver.quit()
1.3 Vor- und Nachteile des impliziten Wartens
Vorteile:
- Einfach und leicht zu verwenden; einmal eingestellt, gilt es für alle Element-Suchvorgänge.
- Geeignet für die meisten einfachen Szenarien.
Nachteile:
- Globales Warten kann zu unnötigen Wartezeiten führen.
- Kann nicht mit bestimmten komplexen Wartebedingungen umgehen, wie z. B. dem Warten darauf, dass ein Element klickbar wird.
2. Explizites Warten (WebDriverWait und expected_conditions)
2.1 Was ist explizites Warten?
Explizites Warten ist ein flexiblerer Wartemechanismus, mit dem Sie Wartebedingungen für bestimmte Operationen festlegen können. Explizites Warten wird normalerweise zusammen mit demWebDriverWaitKlasse undexpected_conditionsModul.
2.2 Wie verwendet man explizites Warten?
Die grundlegende Verwendung von explizitem Warten ist wie folgt:
Beispiel
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import Durch
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Korrekten Treiberpfad festlegen
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Webseite öffnen
driver.get("https://example.com")
# Explizites Warten festlegen, bis zu 10 Sekunden warten, bis das Element erscheint
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "element_id"))
)
# Den Browser schließen
driver.quit()
2.3 Häufige expected_conditions
expected_conditionsDas Modul bietet eine Vielzahl vordefinierter Wartebedingungen. Hier sind einige häufig verwendete:
presence_of_element_located: Warten, bis das Element im DOM erscheint.visibility_of_element_located: Warten, bis das Element im DOM erscheint und sichtbar ist.element_to_be_clickable: Warten, bis das Element anklickbar ist.text_to_be_present_in_element: Warten, bis der Text des Elements den angegebenen Text enthält.
2.4 Vor- und Nachteile des expliziten Wartens
Vorteile:
- Hoch flexibel; Sie können für verschiedene Operationen unterschiedliche Wartebedingungen festlegen.
- Kann mit komplexen Warteszenarien umgehen.
Nachteile:
- Der Code ist relativ komplex und es wird mehr Code benötigt.
- Wartebedingungen müssen für jede Operation separat festgelegt werden.
3. Festes Warten (time.sleep)
3.1 Was ist festes Warten?
Festes Warten ist der einfachste Wartemechanismus. Es pausiert die Skriptausführung für eine angegebene Zeit über dietime.sleep()Methode. Unabhängig davon, ob die Seite fertig geladen wurde, wartet das Skript die angegebene Zeit, bevor es fortfährt.
3.2 Wie verwendet man festes Warten?
Beispiel
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
# Korrekten Treiberpfad festlegen
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Webseite öffnen
driver.get("https://example.com")
# Festes Warten für 5 Sekunden
time.sleep(5)
# Element finden
element = driver.find_element_by_id("element_id")
# Den Browser schließen
driver.quit()
3.3 Vor- und Nachteile von festem Warten
Vorteile:
- Einfach und benutzerfreundlich; geeignet für einfache Testszenarien.
Nachteile:
- Ineffizient und kann zu unnötigen Wartezeiten führen.
- Die Wartezeit kann nicht dynamisch an die Ladebedingungen der Seite angepasst werden.
4. Fluent Wait
Zweck:Wartebedingungen dynamisch festlegen, die Polling-Frequenz anpassen und bestimmte Ausnahmen ignorieren.
Methode:WebDriverWait kombiniert mit polling_every und ignoring
Funktionen:Flexibler, geeignet für Szenarien, die eine dynamische Anpassung der Wartezeiten erfordern.
Beispiel
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import Durch
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
# Korrekten Treiberpfad festlegen
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
driver.get("https://www.example.com")
# Fluent Wait festlegen
wait = WebDriverWait(driver, timeout=10, poll_frequency=1, ignored_exceptions=[NoSuchElementException])
element = wait.until(EC.presence_of_element_located((By.ID, "username")))
5. Zusammenfassung
- Implizites Warten: Geeignet für einfache Szenarien, globales Warten, kann jedoch zu unnötigen Wartezeiten führen.
- Explizites Warten: Geeignet für komplexe Szenarien, sehr flexibel, aber der Code ist relativ komplex.
- Festes Warten: Einfach und benutzerfreundlich, aber ineffizient; für komplexe Testszenarien nicht empfohlen.
- Fluent Wait:: Geeignet für Szenarien, die eine dynamische Anpassung der Wartezeiten erfordern.
In tatsächlichen automatisierten Tests wird empfohlen, je nach den spezifischen Testanforderungen einen geeigneten Wartemechanismus auszuwählen. Im Allgemeinen ist explizites Warten der am meisten empfohlene Ansatz, da es bessere Flexibilität und Effizienz bietet.
6. Umfassendes Beispiel
Das Folgende ist ein vollständiges Beispiel, das zeigt, wie implizite und explizite Wartezeiten verwendet werden:
Beispiel
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.common.by import Durch
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Korrekten Treiberpfad festlegen
service = ChromeService(executable_path="./chromedriver-mac-arm64/chromedriver")
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(service=service, options=options)
# Implizite Wartezeit festlegen
driver.implicitly_wait(5)
# Webseite öffnen
driver.get("https://www.example.com")
# Explizite Wartezeit für die Sichtbarkeit des Elements verwenden
username = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "username"))
)
username.send_keys("testuser")
# Explizite Wartezeit für die Klickbarkeit des Elements verwenden
submit_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit-btn"))
)
submit_button.click()
# Den Browser schließen
driver.quit()