1. Zrozumienie dynamicznych elementów
Zacznijmy od krótkiego wprowadzenia w naturę dynamicznej zawartości. Wyobraź sobie, że jesteś na stronie i w momencie, gdy przewijasz w dół, pojawia się więcej danych, jakbyś był na latającym dywanie, który stale się rozrasta, abyś mógł na nim latać. To się nazywa leniwym ładowaniem albo "lazy loading" — sprytną techniką, która oszczędza zasoby, ładując zawartość tylko w miarę potrzeby. Poleganie na statycznym HTML w takich przypadkach — to jak liczyć na to, że twój kot przyniesie ci poranną kawę.
Czym są dynamiczne elementy?
Dynamiczne elementy to te części strony internetowej, które zmieniają się bez konieczności odświeżania całej strony. Mogą być ładowane przez zapytania AJAX lub wstawiane na stronę za pomocą JavaScript. Ważne jest, aby opanować kilka strategii pracy z tymi elementami, aby twoja aplikacja była równie dynamiczna jak sama zawartość.
2. Strategie interakcji
Czas na praktyczną magię. Aby obsługiwać dynamiczne elementy, potrzebujemy narzędzi, które rozumieją: "Życie to ruch i jestem na to gotowy". W naszym magicznym arsenale znajdzie się Selenium, ponieważ umożliwia ono interakcję z przeglądarką prawie jak człowiek.
Praca z zapytaniami AJAX
AJAX to technologia, która pozwala na aktualizację części strony internetowej bez jej całkowitego ładowania. Jest to wygodne dla użytkowników, ale nieco utrudnia życie twórcom scraperów. Jednak mamy tajną broń — WebDriverWait i expected_conditions z 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
# Konfiguracja sterownika
driver = webdriver.Chrome()
driver.get("https://example-dynamic-site.com")
# Czekanie na pojawienie się elementu
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamic_element_id"))
)
print(element.text)
finally:
driver.quit()
Użycie metod oczekiwania
W pracy z dynamicznymi elementami ważne jest, aby dać przeglądarce czas na osiągnięcie odpowiedniego stanu. Metody czekania, takie jak WebDriverWait w połączeniu z expected_conditions, pozwalają nam płynnie poczekać, aż wszystkie potrzebne elementy się załadują. To jak zmuszenie się do pójścia na siłownię — potrzeba czasu, ale rezultat jest tego wart.
Przykłady:
-
presence_of_element_located— czeka, aż element pojawi się w DOM. -
visibility_of_element_located— czeka, aż element stanie się widoczny. -
element_to_be_clickable— czeka, aż element stanie się klikalny.
Oto przykład, jak można poczekać na klikalność przycisku:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[@id='submit']"))
)
button.click()
Przewijanie strony
Jeśli twoja zawartość ładuje się przy przewijaniu, potrzebujesz sztuki "scrollingu". Selenium pozwala używać JavaScript do przewijania, co pomaga załadować nowe dane.
# Przewijanie do końca strony
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Spróbuj zaimplementować przewijanie w pętli, aby załadować całą zawartość:
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);")
# Poczekaj, aż strona załaduje zawartość
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. Praktyczne przykłady interakcji
Teraz, gdy nauczyliśmy się czekać i obserwować, czas zastosować te umiejętności w praktyce i złapać wszystkie te dynamiczne dane.
Przypuśćmy, że mamy stronę z produktami, która ładuje się przy przewijaniu w dół. Musimy wyciągnąć nazwę i cenę każdego produktu:
products = []
while True:
# Przewijanie w dół
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Czekanie na załadowanie nowych elementów
WebDriverWait(driver, SCROLL_PAUSE_TIME)
# Wydobywanie danych o produktach
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})
# Sprawdzenie, czy załadowało się coś nowego
# (naiwny sposób: jeśli lista items się nie zwiększyła, wychodzimy)
if len(products) == last_known_count:
break
last_known_count = len(products)
Kiedy dynamiczne elementy nie ładują się tak szybko, jakbyśmy chcieli, trzeba wykazać się cierpliwością i sprytem. WebDriverWait z arsenałem warunków, przewijanie strony i wstrzykiwanie JavaScript — to nasze klucze do zdobycia świata dynamicznego contentu. Jak mówił wielki Jedi: "Cierpliwości, młody padawanie". W naszym przypadku cierpliwość oznacza skuteczne scrapowanie wszystkich danych.
Kończymy sesję tak samo, jak po udanym dniu pracy — delikatnie.
driver.quit()
Pamiętaj, na koniec ważne jest, aby upewnić się, że twój kod działa poprawnie, bez awarii i błędów. Tylko wtedy możesz z pewnością powiedzieć: "Misja wykonana". Powodzenia w twojej podróży po świecie dynamicznych danych!
GO TO FULL VERSION