1. 瞭解動態元素
我們先來小小了解一下動態內容的特性。想像一下,你瀏覽一個網站,當你滾動頁面時,更多數據就像魔毯一樣自動出現,一直擴展,讓你能一直飛下去。這叫做懶加載或者 "lazy loading"——一種厲害的技術,能優化資源,僅在需要時才載入內容。在這種情況下只依賴靜態 HTML,簡直就像期待你的貓給你端咖啡一樣不切實際。
什麼是動態元素?
動態元素是網頁上那些不需要重新載入整個頁面就會改變的部分。它們可以透過 AJAX 請求載入,或者通過 JavaScript 嵌入到頁面中。學會處理這些元素的幾種策略是非常重要的,這樣你的應用程式可以和內容一樣動態。
2. 互動策略
讓我們開始實際操作吧!處理動態元素需要工具,能理解「生命在於變化,我已經準備好迎接挑戰」。我們的魔法寶庫中有 Selenium,因為它能像人一樣與瀏覽器互動。
處理 AJAX 請求
AJAX 是一種技術,能部分更新網頁而不需要重新載入整個頁面。對使用者來說很方便,但對開發爬蟲的程序員卻不太友好。不過,我們有秘密武器 —— WebDriverWait 和 Selenium 中的 expected_conditions。
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
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()
滾動頁面
如果你的內容需要滾動來載入,你需要學會 "scroling"。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()
別忘了:最後一定要確保你的代碼能正確工作,沒有崩潰或錯誤。只有這樣,你才能自信地說:「任務完成」。祝你在動態數據的世界旅程中好運!
GO TO FULL VERSION