Selenium trong tự động hóa trình duyệt và thu thập dữ liệu

Selenium là gì?

Selenium là một công cụ mạnh mẽ dùng để kiểm thử ứng dụng Web, có khả năng mô phỏng hành vi người dùng thật thông qua thao tác trực tiếp trên trình duyệt. Nó hỗ trợ nhiều trình duyệt phổ biến như Google Chrome, Mozilla Firefox, Safari, Opera và Internet Explorer trên các hệ điều hành khác nhau. Các tính năng chính bao gồm:

  • Kiểm tra tương thích giữa ứng dụng và nhiều loại trình duyệt.
  • Tự động hóa quy trình kiểm thử chức năng (regression testing).
  • Hỗ trợ ghi lại thao tác và sinh mã kiểm thử bằng nhiều ngôn ngữ lập trình như Java, .NET, Python, Perl…

Ứng dụng của Selenium trong web scraping

Trong lĩnh vực thu thập dữ liệu, Selenium được sử dụng rộng rãi nhờ khả năng xử lý nội dung tải động (dynamic content) mà các công cụ truyền thống như requests + BeautifulSoup không thể truy cập được. Ưu điểm nổi bật:

  • Thu thập dữ liệu động: Dữ liệu nào hiển thị trên giao diện người dùng đều có thể lấy được.
  • Thực hiện đăng nhập tự động: Xử lý xác thực phức tạp như form JavaScript, reCAPTCHA (kết hợp với giải pháp khác), hoặc đăng nhập OAuth.

Cài đặt và cấu hình cơ bản

Để bắt đầu sử dụng Selenium với Python, cần thực hiện các bước sau:

  1. Cài đặt thư viện: pip install selenium
  2. Tải về phiên bản phù hợp của trình điều khiển (driver) cho trình duyệt mong muốn (ví dụ: ChromeDriver cho Google Chrome).
  3. Đảm bảo phiên bản driver tương thích với phiên bản trình duyệt đang sử dụng.

Ví dụ cơ bản với Python

Dưới đây là đoạn mã minh họa cách mở trang Baidu, thao tác với cài đặt, nhập từ khóa tìm kiếm và điều hướng đến kết quả:

from time import sleep
from selenium import webdriver

# Khởi tạo trình điều khiển Chrome
driver = webdriver.Chrome(executable_path=r'chromedriver.exe')

# Mở trang chủ Baidu
driver.get("https://www.baidu.com")

# Nhấp vào menu "Cài đặt"
driver.find_element_by_xpath('//*[@id="s-usersetting-top"]').click()
sleep(1)

# Vào mục "Cài đặt tìm kiếm"
driver.find_element_by_link_text("Cài đặt tìm kiếm").click()
sleep(1)

# Chọn tùy chọn hiển thị 50 kết quả mỗi trang
driver.find_element_by_xpath('//input[@value="50"]').click()
sleep(1)

# Lưu thay đổi
driver.find_element_by_class_name("prefpanelgo").click()

# Xử lý popup cảnh báo (nếu có)
try:
    alert = driver.switch_to.alert
    alert.accept()
except:
    pass

# Tìm ô tìm kiếm, nhập từ khóa và thực hiện tìm
search_box = driver.find_element_by_id("kw")
search_box.send_keys("hình ảnh đẹp")
sleep(1)

search_button = driver.find_element_by_id("su")
search_button.click()
sleep(2)

# Mở liên kết đầu tiên trong kết quả tìm kiếm
first_result = driver.find_element_by_xpath('//*[@id="1"]/h3/a')
first_result.click()

# Giữ cửa sổ mở trong 10 giây để quan sát
sleep(10)

# Đóng trình duyệt
driver.quit()

Tương tác với các phần tử và thực thi JavaScript

Selenium cho phép định vị phần tử bằng nhiều cách: ID, class name, XPath, CSS selector… Ngoài ra, có thể thực thi đoạn mã JavaScript để thao tác sâu hơn với trang web:

from selenium import webdriver
import time

browser = webdriver.Chrome(executable_path='chromedriver.exe')
browser.get('https://www.jd.com')

# Tìm ô tìm kiếm và nhập nội dung
input_field = browser.find_element_by_css_selector('#key')
input_field.send_keys('MacBook Pro')

# Nhấn nút tìm kiếm
search_btn = browser.find_element_by_css_selector('.button')
search_btn.click()

time.sleep(2)

# Cuộn xuống cuối trang bằng JavaScript
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)

# Lấy mã nguồn HTML sau khi đã render đầy đủ
html_content = browser.page_source

# In nội dung (có thể phân tích bằng BeautifulSoup nếu cần)
print(html_content[:1000])  # In 1000 ký tự đầu

browser.quit()

Thu thập dữ liệu từ trang phân trang động

Một số trang web tải dữ liệu theo từng trang thông qua AJAX. Selenium giúp lặp lại thao tác nhấn nút "Trang tiếp" để thu thập toàn bộ dữ liệu:

from selenium import webdriver
import time
from lxml import etree

driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('http://125.35.6.84:81/xk/')
time.sleep(2)

pages_html = []

for _ in range(4):  # Thu thập 4 trang
    pages_html.append(driver.page_source)
    try:
        next_btn = driver.find_element_by_id('pageIto_next')
        next_btn.click()
        time.sleep(1.5)
    except:
        break  # Dừng nếu không còn nút tiếp

# Phân tích từng trang đã lưu
for page in pages_html:
    tree = etree.HTML(page)
    items = tree.xpath('//ul[@id="gzlist"]/li')
    for item in items:
        company = item.xpath('./dl/@title')[0] if item.xpath('./dl/@title') else ''
        license_id = item.xpath('./ol/@title')[0] if item.xpath('./ol/@title') else ''
        print(f"{company}: {license_id}")

driver.quit()

Sử dụng chuỗi hành động (Action Chains)

Khi cần mô phỏng các thao tác kéo thả (drag and drop), phải dùng lớp ActionChains. Đặc biệt chú ý nếu phần tử nằm trong iframe – cần chuyển ngữ cảnh trước:

from selenium import webdriver
from selenium.webdriver import ActionChains
import time

driver = webdriver.Chrome(executable_path='chromedriver.exe')
driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')

# Chuyển sang iframe chứa phần tử
driver.switch_to.frame('iframeResult')

draggable = driver.find_element_by_id('draggable')
actions = ActionChains(driver)
actions.click_and_hold(draggable)

# Di chuyển từng bước nhỏ
for _ in range(5):
    actions.move_by_offset(15, 5).perform()
    time.sleep(0.3)

actions.release()  # Thả đối tượng
time.sleep(2)
driver.quit()

Chế độ vô hình (Headless Browser)

Để tăng hiệu suất và chạy ngầm, có thể kích hoạt chế độ headless – không hiển thị giao diện đồ họa:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_opts = Options()
chrome_opts.add_argument('--headless')
chrome_opts.add_argument('--disable-gpu')
chrome_opts.add_argument('--no-sandbox')

driver = webdriver.Chrome(executable_path='chromedriver.exe', options=chrome_opts)
driver.get('https://www.cnblogs.com')
print(driver.page_source)
driver.quit()

Thiết lập proxy mạng

Để ẩn địa chỉ IP hoặc truy cập qua máy chủ trung gian, có thể cấu hình proxy trong tùy chọn khởi động:

from selenium import webdriver

proxy_server = "113.74.61.232:28803"
options = webdriver.ChromeOptions()
options.add_argument(f'--proxy-server=http://{proxy_server}')

browser = webdriver.Chrome(executable_path='chromedriver.exe', options=options)
browser.get('https://httpbin.org/ip')
print(browser.page_source)
browser.quit()

Tránh bị phát hiện là bot

Một số website (như Taobao, Alibaba) có cơ chế phát hiện và chặn trình duyệt tự động. Để giảm khả năng bị phát hiện, có thể thêm các tùy chỉnh đặc biệt:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)

driver = webdriver.Chrome(executable_path='chromedriver.exe', options=options)
# Ngăn WebDriver thông báo rằng nó đang bị kiểm soát bởi phần mềm tự động
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
    'source': '''
        Object.defineProperty(navigator, 'webdriver', {
          get: () => false
        })
    '''
})

driver.get('https://www.taobao.com')

Thẻ: selenium python web-scraping automation headless-browser

Đăng vào ngày 27 tháng 7 lúc 22:08