1. Hiểu về các phần tử động
Hãy bắt đầu với một chút giải thích về bản chất của nội dung động. Hãy tưởng tượng bạn đang ở trên một trang web, và khi bạn cuộn xuống, nhiều dữ liệu hơn sẽ xuất hiện, giống như một tấm thảm bay thần kỳ, luôn mở rộng để bạn có thể bay trên đó. Điều này được gọi là tải chậm hoặc "lazy loading" — một kỹ thuật tuyệt vời tiết kiệm tài nguyên bằng cách chỉ tải nội dung khi cần thiết. Dựa vào HTML tĩnh trong những trường hợp này giống như hy vọng rằng chú mèo của bạn sẽ mang cà phê sáng tới.
Phần tử động là gì?
Phần tử động là những phần của trang web thay đổi mà không cần làm mới toàn bộ trang. Chúng có thể được tải qua các yêu cầu AJAX hoặc nhúng vào trang thông qua JavaScript. Quan trọng là bạn phải nắm được một số chiến lược để làm việc với những phần tử này, để ứng dụng của bạn năng động như chính nội dung đó.
2. Các chiến lược tương tác
Bây giờ hãy bắt đầu làm một số "phép thuật thực tiễn". Để xử lý các phần tử động, chúng ta cần công cụ hiểu rằng: "Cuộc sống là chuyển động, và tôi đã sẵn sàng cho điều đó". Trong kho phép thuật của chúng ta, Selenium là lựa chọn số một vì nó cho phép tương tác với trình duyệt gần như con người.
Làm việc với các yêu cầu AJAX
AJAX là công nghệ cho phép cập nhật một phần của trang web mà không cần tải lại toàn bộ. Điều này tiện lợi cho người dùng nhưng có thể gây khó khăn cho các nhà phát triển thu nhập dữ liệu. Tuy nhiên, chúng ta có một vũ khí bí mật — WebDriverWait và expected_conditions từ 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
# Cấu hình driver
driver = webdriver.Chrome()
driver.get("https://example-dynamic-site.com")
# Chờ đợi phần tử xuất hiện
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "dynamic_element_id"))
)
print(element.text)
finally:
driver.quit()
Sử dụng các phương pháp chờ
Khi làm việc với các phần tử động, quan trọng là phải cho trình duyệt thời gian để đến trạng thái mong muốn. Các phương pháp chờ như WebDriverWait kết hợp với expected_conditions cho phép chúng ta chờ đợi tất cả phần tử cần thiết được tải lên một cách mượt mà. Nó giống như kéo bản thân tới phòng tập — cần có thời gian, nhưng kết quả thì đáng giá.
Ví dụ:
-
presence_of_element_located— chờ cho đến khi phần tử xuất hiện trong DOM. -
visibility_of_element_located— chờ cho đến khi phần tử xuất hiện đầy đủ (có thể nhìn thấy). -
element_to_be_clickable— chờ cho đến khi phần tử có thể được nhấp.
Ví dụ, đây là cách chờ đợi một nút có thể nhấp:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[@id='submit']"))
)
button.click()
Cuộn trang
Nếu nội dung của bạn tải theo cách cuộn, bạn sẽ cần một chút kỹ thuật "scrolling". Selenium cho phép sử dụng JavaScript để cuộn, điều này giúp tải dữ liệu mới.
# Cuộn đến cuối trang
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
Hãy thử thực hiện cuộn trong một vòng lặp để tải toàn bộ nội dung:
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);")
# Chờ đợi trang tải thêm nội dung
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. Các ví dụ thực tế
Bây giờ khi chúng ta đã học cách chờ đợi và quan sát, đã đến lúc áp dụng những kỹ năng này vào thực tế và nắm bắt mọi dữ liệu động.
Giả sử chúng ta có một trang với các sản phẩm tải khi cuộn xuống. Chúng ta cần trích xuất tên và giá của mỗi sản phẩm:
products = []
while True:
# Cuộn xuống
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# Chờ đợi các phần tử mới được tải lên
WebDriverWait(driver, SCROLL_PAUSE_TIME)
# Trích xuất dữ liệu sản phẩm
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})
# Kiểm tra xem có gì mới không
# (cách cơ bản: nếu danh sách items không tăng, thoát)
if len(products) == last_known_count:
break
last_known_count = len(products)
Khi các phần tử động không tải nhanh như mong đợi, chúng ta cần kiên nhẫn và khéo léo. WebDriverWait với các điều kiện của nó, cuộn trang và chèn JavaScript — đó là chìa khóa để chinh phục thế giới nội dung động. Như lời của một vị Jedi vĩ đại: "Kiên nhẫn, đồ đệ trẻ của ta". Trong trường hợp của chúng ta, kiên nhẫn có nghĩa là thu thập dữ liệu thành công.
Kết thúc phiên làm việc cũng giống như sau một ngày dài làm việc thành công — thật cẩn thận.
driver.quit()
Đừng quên: cuối cùng điều quan trọng là đảm bảo rằng mã của bạn chạy chính xác, không phát sinh lỗi. Chỉ khi đó bạn mới có thể tự tin nói: "Nhiệm vụ đã hoàn thành". Chúc bạn may mắn trong hành trình khám phá thế giới dữ liệu động!
GO TO FULL VERSION