Списки и страницы
Данные редко помещаются на одной странице: каталоги разбиты на страницы, ленты подгружаются кнопкой «Показать ещё». Программа должна пройти их все.
Страница за страницей
names = []
while True:
names += [li.text for li in driver.find_elements(By.CSS_SELECTOR, "#list li")]
button = driver.find_element(By.ID, "next")
if not button.is_enabled(): # последняя страница
break
button.click()
Порядок важен: сначала прочитать текущую страницу, потом решать, идти ли дальше. Иначе последняя страница потеряется.
Признак конца бывает разным: кнопка неактивна (is_enabled()), кнопки нет (find_elements вернул пустой список), адрес не изменился, пришёл пустой список.
Дозагрузка
Если после нажатия данные приходят не сразу, нужно ждать изменения. Условие ожидания может быть любой функцией от driver:
before = len(driver.find_elements(By.CSS_SELECTOR, "div.comment"))
driver.find_element(By.ID, "more").click()
WebDriverWait(driver, 5).until(lambda d: len(d.find_elements(By.CSS_SELECTOR, "div.comment")) > before)
Функция вызывается каждые полсекунды, пока не вернёт истинное значение.
«Протухшие» элементы
Когда страница заменяет содержимое (новая страница каталога), старые найденные элементы перестают существовать. Обращение к ним — StaleElementReferenceException. Поэтому элементы ищут заново после каждого действия, а дождаться замены можно условием EC.staleness_of(старый_элемент).
JavaScript из Python
driver.execute_script("window.scrollTo(0, document.body.scrollHeight)") # прокрутить вниз
title = driver.execute_script("return document.title")
driver.execute_script("arguments[0].click()", element) # клик через JS
Это запасной инструмент: когда обычных действий не хватает (бесконечная прокрутка, перекрытые элементы).
Числа со страницы
На страницах числа записаны «для людей»: 1 299 ₽, 12,5 %. Перед расчётами их чистят: оставляют цифры (ch.isdigit()), заменяют запятую на точку.
Итог
- прочитать страницу → проверить конец → перейти дальше;
- свои условия ожидания:
until(lambda d: …); - после обновления страницы элементы ищут заново;
execute_scriptдля прокрутки и особых случаев; числа чистят перед расчётом.