Ожидания
Многие сайты показывают страницу сразу, а данные догружают чуть позже: таблица появляется через секунду, кнопка включается после проверки формы. Если программа ищет элемент сразу — его ещё нет.
Плохой способ — time.sleep
import time
button.click()
time.sleep(5) # «наверное, за 5 секунд загрузится»
driver.find_element(By.ID, "data")
Если сайт ответил за 0.2 секунды — программа зря ждёт ещё 4.8. Если за 6 — всё равно падает. Сотни таких ожиданий превращают программу в черепаху.
Хороший способ — WebDriverWait
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10) # ждать не больше 10 секунд
element = wait.until(EC.visibility_of_element_located((By.ID, "data")))
print(element.text)
until проверяет условие каждые полсекунды и возвращает результат, как только условие выполнилось. Не дождались — исключение TimeoutException.
Частые условия (EC.…):
| Условие | Ждёт, пока |
|---|---|
presence_of_element_located(лок) |
элемент появится в HTML |
visibility_of_element_located(лок) |
элемент станет видимым |
element_to_be_clickable(лок) |
элемент видим и активен |
text_to_be_present_in_element(лок, текст) |
текст элемента содержит строку |
invisibility_of_element_located(лок) |
элемент исчезнет (например, «спиннер») |
url_contains(часть) |
адрес страницы изменится |
Локатор — кортеж (By.ID, "data"), поэтому скобки двойные.
Что делать, если не дождались
from selenium.common.exceptions import TimeoutException
try:
wait.until(EC.text_to_be_present_in_element((By.ID, "status"), "Итог:"))
except TimeoutException:
print("сервер не ответил")
Выбирайте условие, которое действительно означает «готово»: элемент со словом «Загрузка…» виден сразу, но результата в нём ещё нет.
Итог
- данные догружаются — элементы появляются не сразу;
WebDriverWait(driver, секунды).until(EC.…)вместоtime.sleep;visibility_of_element_located,text_to_be_present_in_element,element_to_be_clickable;TimeoutException, если не дождались.