All posts
Khai Phá Dữ Liệu Web Với Selenium

Khai Phá Dữ Liệu Web Với Selenium

Nhan Bui T.'s avatarNhan Bui T.
Table of Contents20 sections

Trong kỷ nguyên của AI và Machine Learning, dữ liệu chính là "dầu mỏ" mới. Thế nhưng, không phải lúc nào chúng ta cũng có sẵn một file CSV sạch đẹp hay một REST API công khai để chỉ cần GET là xong.

Hãy tưởng tượng bạn được giao nhiệm vụ xây dựng một mô hình phân loại các loài hoa (Flora Classification). Bạn tìm thấy một trang web thư viện thực vật có hàng ngàn hình ảnh chất lượng cao, kèm theo các thông tin có cấu trúc như Tên khoa học, Họ thực vật, Môi trường sống, và Giá tham khảo.

Trang web này sử dụng JavaScript (React/Vue) để render nội dung, hình ảnh chỉ tải khi bạn cuộn trang (Lazy Loading/Infinite Scroll), và hoàn toàn không có API public.

Làm sao để thu thập hàng ngàn mẫu dữ liệu này mà không tốn cả tuần ngồi click thủ công?

Đây chính là lúc Selenium phát huy sức mạnh.


1. Selenium Là Gì Và Điểm Mạnh Cốt Lõi Khi Scraping Dữ Liệu

Ban đầu, Selenium được sinh ra như một công cụ tự động hóa kiểm thử web (End-to-End Testing). Tuy nhiên, nhờ khả năng điều khiển trình duyệt thật (Chrome, Firefox, Edge...) như người dùng thực, nó đã trở thành "vũ khí hạng nặng" trong lĩnh vực Web Scraping.

Điểm mạnh cốt lõi

Xử lý JavaScript động (Client-side Rendering)

Selenium thực thi JavaScript nguyên bản trên trình duyệt. Mọi dữ liệu được render sau khi trang load xong đều có thể được truy cập.

Tương tác như người thật

Hỗ trợ:

  • Click

  • Gõ bàn phím

  • Scroll

  • Hover

  • Upload file

  • Xử lý Popup

  • Iframe

  • Multiple Tabs

Vượt qua một số cơ chế Anti-bot cơ bản

Vì Selenium điều khiển một trình duyệt thật nên các thông tin như:

  • User-Agent

  • Cookies

  • Session

  • LocalStorage

đều hoạt động giống người dùng thông thường hơn so với việc chỉ gửi HTTP Request.


2. Khi nào sử dụng Selenium, khi nào sử dụng BeautifulSoup

Đối với Dev, việc chọn sai công cụ thu thập dữ liệu có thể làm giảm hiệu năng hệ thống đi hàng chục lần.

Tiêu chí

BeautifulSoup + Requests

Selenium

Cơ chế hoạt động

HTTP GET/POST lấy HTML

Khởi chạy trình duyệt thật

Xử lý JavaScript

Không

Tốc độ

Rất nhanh

Chậm hơn

RAM / CPU

Ít

Cao

Tương tác UI

Không

Click, Scroll, Input

Quy tắc vàng

Luôn ưu tiên Requests + BeautifulSoup nếu:

  • Trang trả về HTML tĩnh

  • Có REST API ẩn trong DevTools → Network

Chỉ sử dụng Selenium khi:

  • Website render bằng React/Vue/Angular

  • Infinite Scroll

  • Click "Load More"

  • Lazy Loading

  • Popup

  • Login

  • CAPTCHA nhẹ

  • Các thao tác yêu cầu tương tác người dùng


3. Case Study: Thu Thập Dữ Liệu Thực Vật (Text + Image)

Kỹ thuật 1: Explicit Wait

Không nên sử dụng time.sleep().

Hãy dùng WebDriverWait để chỉ chờ đến khi Element thật sự xuất hiện.

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-flower-db.com/catalog")

try:
    flower_cards = WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located(
            (By.CLASS_NAME, "flower-card")
        )
    )

    print(f"Đã tìm thấy {len(flower_cards)} loài hoa!")

finally:
    pass

Kỹ thuật 2: Infinite Scroll + Lazy Loading

Nhiều website chỉ tải ảnh khi người dùng cuộn xuống cuối trang.

Ví dụ:

import time
import requests

driver.execute_script(
    "window.scrollTo(0, document.body.scrollHeight);"
)

time.sleep(2)

flowers_data = []

cards = driver.find_elements(By.CLASS_NAME, "flower-card")

for card in cards:

    name = card.find_element(By.TAG_NAME, "h3").text

    family = card.find_element(
        By.CLASS_NAME,
        "family-name"
    ).text

    img_url = card.find_element(
        By.TAG_NAME,
        "img"
    ).get_attribute("src")

    flowers_data.append({
        "name": name,
        "family": family,
        "img_url": img_url
    })

for idx, item in enumerate(flowers_data):

    img = requests.get(item["img_url"]).content

    with open(
        f"data/flower_{idx}.jpg",
        "wb"
    ) as f:
        f.write(img)

4. Best Practices Giúp Tối Ưu Selenium

4.1 Sử dụng Headless Mode

Khi chạy trên Server hoặc CI/CD, luôn bật Headless Mode.

from selenium import webdriver

options = webdriver.ChromeOptions()

options.add_argument("--headless=new")

driver = webdriver.Chrome(
    options=options
)

4.2 Block Image/CSS Nếu Chỉ Cần Text

Nếu mục tiêu chỉ là thu thập dữ liệu dạng text, hãy tắt:

  • Images

  • Fonts

  • CSS

để giảm thời gian tải trang và tiết kiệm tài nguyên.


4.3 Hybrid Selenium + BeautifulSoup

Đây là cách làm được nhiều Dev sử dụng trong thực tế.

Ý tưởng:

  • Selenium chỉ dùng để:

  • Login

  • Scroll

  • Click

  • Render JavaScript

Sau khi dữ liệu đã xuất hiện đầy đủ:

html = driver.page_source

Tiếp theo:

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")

Việc parse HTML bằng BeautifulSoup nhanh hơn rất nhiều so với việc gọi:

find_element()
find_elements()

liên tục bằng Selenium.


5. Duy Trì Phiên Đăng Nhập (Session Persistence)

Một khó khăn thường gặp khi thu thập dữ liệu là website yêu cầu người dùng phải đăng nhập trước khi truy cập nội dung.

Thay vì mỗi lần chạy chương trình đều phải:

  • Mở trình duyệt

  • Điền tài khoản

  • Nhập mật khẩu

  • Xác thực OTP (nếu có)

Selenium cho phép lưu lại trạng thái đăng nhập thông qua Cookies. Ở lần chạy tiếp theo, chỉ cần nạp lại Cookies là có thể tiếp tục sử dụng phiên đăng nhập (nếu Cookies vẫn còn hiệu lực).

Đây là kỹ thuật Session Persistence, không phải bypass authentication.

5.1 Lưu Cookies ra file

Sau khi người dùng đăng nhập thành công:

import pickle

cookies = driver.get_cookies()

with open("cookies.pkl", "wb") as f:
    pickle.dump(cookies, f)

File cookies.pkl sẽ chứa toàn bộ Cookies của website.


5.2 Nạp Cookies ở lần chạy sau

import pickle

driver.get("https://example.com")

with open("cookies.pkl", "rb") as f:
    cookies = pickle.load(f)

for cookie in cookies:
    driver.add_cookie(cookie)

driver.refresh()

Sau khi refresh, Selenium sẽ gửi lại Cookies đến server và nếu phiên đăng nhập vẫn còn hiệu lực thì người dùng sẽ được đăng nhập tự động.


5.3 Một số lưu ý

  • Cookies có thời gian hết hạn (Expiration Time).

  • Một số website sẽ thu hồi Cookies sau khi đăng xuất hoặc đổi mật khẩu.

  • Một số hệ thống còn kiểm tra:

  • IP Address

  • User-Agent

  • Device Fingerprint

  • CSRF Token

  • Với các website có cơ chế bảo mật cao, chỉ lưu Cookies có thể chưa đủ để khôi phục phiên làm việc.


5.4 Khi nào nên sử dụng?

Kỹ thuật lưu Cookies đặc biệt hữu ích khi crawl dữ liệu từ:

  • Dashboard nội bộ

  • Website yêu cầu đăng nhập

  • Trang quản trị

  • Hệ thống CRM

  • Website thương mại điện tử

  • Diễn đàn hoặc mạng xã hội (khi được phép truy cập)

Việc tái sử dụng phiên đăng nhập giúp giảm thời gian khởi tạo và hạn chế việc phải đăng nhập lặp lại trong quá trình thu thập dữ liệu.


6. Khi Nào Nên Dùng Selenium?

Selenium phù hợp khi website có một hoặc nhiều đặc điểm sau:

  • React

  • Vue

  • Angular

  • JavaScript Rendering

  • Login

  • Infinite Scroll

  • Lazy Loading

  • Popup

  • Modal

  • Click Load More

  • Upload File

  • Dynamic Table

Nếu website chỉ trả về HTML tĩnh thì Requests + BeautifulSoup gần như luôn là lựa chọn tốt hơn.


Tổng Kết

Selenium không phải là giải pháp tối ưu cho mọi bài toán Web Scraping. Nó chậm hơn Requests, tiêu tốn nhiều RAM và CPU hơn, nhưng lại cực kỳ mạnh khi cần:

  • Render JavaScript

  • Tương tác như người dùng

  • Thu thập dữ liệu sau các thao tác UI

  • Xử lý các website SPA hiện đại

Trong thực tế, cách tiếp cận hiệu quả nhất thường là kết hợp Selenium và BeautifulSoup:

  • Selenium xử lý tương tác và render nội dung động.

  • BeautifulSoup đảm nhiệm việc phân tích HTML và trích xuất dữ liệu nhanh chóng.

Việc lựa chọn đúng công cụ cho từng bài toán sẽ giúp pipeline thu thập dữ liệu của bạn đạt được sự cân bằng giữa tốc độ, độ ổn định và khả năng mở rộng.