1. Розуміння динамічних елементів
Давайте почнемо з невеликого екскурсу в природу динамічного контенту. Уявіть, що ви знаходитесь на сайті, і щойно ви прокручуєте сторінку вниз, з'являється більше даних, як чарівний килим-літак, який постійно розширюється, щоб ви могли на ньому літати. Це називається ледачим завантаженням або "lazy loading" — хитра техніка, яка дозволяє економити ресурси, завантажуючи контент тільки по мірі його необхідності. Покладатися на статичний HTML у таких випадках — як сподіватися, що ваш кіт принесе ранкову каву.
Що таке динамічні елементи?
Динамічні елементи — це ті частини веб-сторінки, які змінюються без необхідності оновлення всієї сторінки. Вони можуть завантажуватися через AJAX-запити або вбудовуватися на сторінку за допомогою JavaScript. Важливо освоїти декілька стратегій роботи з такими елементами, щоб ваш додаток був таким же динамічним, як і сам контент.
2. Стратегії взаємодії
Приступимо до практичної магії. Щоб обробити динамічні елементи, нам потрібні інструменти, які розуміють: "Життя — це рух, і я готовий до цього". У нашому чарівному арсеналі буде Selenium, адже він дозволяє взаємодіяти з браузером майже як людина.
Робота з AJAX-запитами
AJAX — це технологія, яка дає змогу оновлювати частину веб-сторінки, не завантажуючи її повністю. Це зручно для користувачів, але трохи ускладнює життя розробникам скрейперів. Проте у нас є секретна зброя — WebDriverWait та expected_conditions із Selenium.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# Налаштовуємо драйвер
driver = webdriver.Chrome()
driver.get("https://example-dynamic-site.com")
# Очікування появи елемента
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamic_element_id"))
)
print(element.text)
finally:
driver.quit()
Використання методів очікування
При роботі з динамічними елементами важливо давати браузеру час, щоб "дійти" до потрібного стану. Методи очікування, такі як WebDriverWait у поєднанні з expected_conditions, дозволяють нам плавно дочекатися завантаження всіх потрібних елементів. Це як затащити себе в спортзал — потрібен час, але результат того вартий.
Приклади:
-
presence_of_element_located— чекає, поки елемент з'явиться в DOM. -
visibility_of_element_located— чекає, поки елемент стане видимим. -
element_to_be_clickable— чекає, поки елемент стане клікабельним.
Ось, наприклад, як можна дочекатися клікабельності кнопки:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[@id='submit']"))
)
button.click()
Прокрутка сторінки
Якщо ваш контент завантажується при прокрутці, вам знадобиться мистецтво "скролінгу". Selenium дозволяє використовувати JavaScript для прокрутки, що допоможе завантажити нові дані.
# Прокрутка до кінця сторінки
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Спробуйте реалізувати прокрутку в циклі, щоб підвантажити весь контент:
SCROLL_PAUSE_TIME = 2
driver.get("https://example.com/dynamic-content")
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Зачекайте, щоб сторінка підвантажувала контент
WebDriverWait(driver, SCROLL_PAUSE_TIME)
new_height = driver.execute_script("return document.body.scrollHeight")
if new_height == last_height:
break
last_height = new_height
3. Практичні приклади взаємодії
Тепер, коли ми навчилися чекати і спостерігати, час застосувати ці навички на практиці та зловити всі ці динамічні дані.
Припустимо, у нас є сторінка з товарами, яка завантажується при прокрутці вниз. Нам потрібно отримати назву і ціну кожного продукту:
products = []
while True:
# Прокрутка вниз
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Чекати завантаження нових елементів
WebDriverWait(driver, SCROLL_PAUSE_TIME)
# Отримання даних товарів
items = driver.find_elements(By.CLASS_NAME, "product-item")
for item in items:
name = item.find_element(By.CLASS_NAME, 'product-name').text
price = item.find_element(By.CLASS_NAME, 'product-price').text
products.append({'name': name, 'price': price})
# Перевірка, чи завантажилося щось нове
# (наївний спосіб: якщо список items не збільшився, виходимо)
if len(products) == last_known_count:
break
last_known_count = len(products)
Коли динамічні елементи не завантажуються так швидко, як би нам хотілося, доводиться проявляти терпіння та вправність. WebDriverWait зі своїм арсеналом умов, прокрутка сторінки і JavaScript-ін'єкції — це наш ключ до завоювання світу динамічного контенту. Як казав великий Джедай: "Терпіння, мій юний падаване". У нашому випадку терпіння означає успішний скрейпінг усіх даних.
Завершуємо сесію так само, як після успішного робочого дня — акуратно.
driver.quit()
Не забудьте: насамкінець важливо переконатися, що ваш код працює коректно, без збоїв та помилок. Тільки так ви можете із впевненістю сказати: "Місія виконана". Бажаю успіхів у вашій подорожі світом динамічних даних!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ