🎯 Trình duyệt đám mây tùy chỉnh, chống phát hiện được hỗ trợ bởi Chromium tự phát triển, thiết kế dành cho trình thu thập dữ liệu webtác nhân AI. 👉Dùng thử ngay
Quay lại blog

Selenium Web Scraping: Hướng Dẫn Thực Tế Bằng Python

Daniel Kim
Daniel Kim

Lead Scraping Automation Engineer

05-Aug-2026

Tóm tắt:

  • Selenium điều khiển một trình duyệt Chrome thực qua giao thức WebDriver, vì vậy nó thấy được DOM mà một trang xây dựng bằng JavaScript — nội dung mà một yêu cầu HTTP thông thường không nhận được.
  • Một lần chạy trực tiếp bên dưới đọc tất cả mười trích dẫn từ một trang demo mà gửi một container trống và lấp đầy nó ở phía client; trang tương tự trả về không có hàng nào cho một requests.get đơn giản.
  • Selenium hiện đại tự động nhận diện driver của nó: Selenium Manager khớp ChromeDriver với Chrome được cài đặt trên máy của bạn, vì vậy webdriver.Chrome(options=...) hoạt động mà không cần tải xuống thủ công.
  • Chi phí thực sự của Selenium là chi phí vận hành — mỗi worker là một trình duyệt đầy đủ rời khỏi IP của bạn, điều này nặng nề để mở rộng và dễ dàng cho các hệ thống chống bot giới hạn tỷ lệ.
  • Điểm xoay chuyển giới hạn trung thực gửi cùng một URL tới Scrapeless Universal Scraping API, cái chép trang server-side và trả về HTML hoàn chỉnh, mà không cần bạn phải chạy hay mở rộng trình duyệt.
  • Nhận một khóa API Scrapeless trên kế hoạch miễn phí và tự chạy cả hai phần.

Selenium làm gì cho việc thu thập dữ liệu

Selenium tự động hóa một trình duyệt thực. Mã Python của bạn giao tiếp với ChromeDriver qua giao thức WebDriver, ChromeDriver điều khiển Chrome, và Chrome làm những gì một trình duyệt thực hiện: nó yêu cầu trang, chạy các script, và xây dựng DOM. Phần cuối cùng đó là lý do các scraper tìm đến nó. Một trang lắp ráp nội dung của nó ở phía client — một lưới sản phẩm được hiển thị bởi một framework, một feed đến qua một yêu cầu nền — thì trống trong HTML thô và chỉ hoàn chỉnh sau khi các script được chạy. Selenium chờ đợi việc thực thi đó và đưa cho bạn trang hoàn chỉnh.

Đánh đổi là khối lượng. Selenium chạy một Chrome thực mỗi phiên, điều này tiêu tốn bộ nhớ và thời gian khởi động, và yêu cầu xuất phát từ IP của máy bạn. Đối với một vài trang thì điều này là ổn. Hướng dẫn này xây dựng scraper Selenium hoạt động trước tiên, sau đó chỉ ra thời điểm mà việc chạy các trình duyệt của bạn không còn tiết kiệm và cách khắc phục điều đó. Mọi đường đi trong code ở đây đều thực hiện trên trang sống.

Cài đặt

Cài đặt các bindings Python của Selenium:

bash Copy
pip install selenium

Bạn không cài đặt ChromeDriver bằng tay. Từ phiên bản 4.6, Selenium gửi công cụ WebDriver của Selenium với Selenium Manager, cái nhận diện Chrome của bạn và xác định driver tương ứng khi sử dụng lần đầu. Bạn cần cài đặt Google Chrome mới gần đây; các bindings sẽ xử lý phần còn lại.

Cấu hình

Đối với điểm chuyển đổi sau trong hướng dẫn này, đặt khóa API Scrapeless của bạn vào môi trường để nó không bao giờ xuất hiện trong mã nguồn:

bash Copy
export SCRAPELESS_API_KEY="your_scrapeless_api_key"

Thực hiện cơ bản: hiển thị một trang JavaScript

Chỉ định Selenium tới một trang mà xây dựng hàng của nó ở phía client, và các phần tử sẽ xuất hiện khi điều hướng quay trở lại. Demo bên dưới gửi một container trống và điền nó bằng JavaScript; đánh dấu thô không chứa bất kỳ nút .quote nào, trong khi DOM được trình duyệt hiển thị có mười nút vì Chrome đã chạy các script trước đó, theo mô hình phân tích và lập trình HTML.

python Copy
import tempfile
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

opts = Options()
opts.add_argument("--headless=new")
opts.add_argument("--no-sandbox")
opts.add_argument("--disable-dev-shm-usage")
opts.add_argument(f"--user-data-dir={tempfile.mkdtemp()}")

driver = webdriver.Chrome(options=opts)   # Selenium Manager xác định driver
try:
    driver.get("https://quotes.toscrape.com/js/")
    quotes = driver.find_elements(By.CSS_SELECTOR, ".quote")
    print("số lượng khối trích dẫn trên trang JS:", len(quotes))
    print("tác giả đầu tiên:", quotes[0].find_element(By.CSS_SELECTOR, ".author").text)
finally:
    driver.quit()

Chạy lệnh in ra số lượng và bản ghi đầu tiên:

text Copy
số lượng khối trích dẫn trên trang JS: 10
tác giả đầu tiên: Albert Einstein

Cờ --headless=new chạy Chrome mà không có cửa sổ hiển thị, điều này là điều bạn muốn trên một máy chủ. --no-sandbox--disable-dev-shm-usage giữ Chrome ổn định bên trong các container và môi trường hạn chế, và --user-data-dir thải loại cung cấp cho mỗi lần chạy một hồ sơ riêng để các phiên song song không bị va chạm.

Mẫu nâng cao: chờ đợi và chọn lựa

driver.get trả lại khi tài liệu đã tải, nhưng một phần tử được xây dựng bởi script có thể xuất hiện ngay sau đó. Thay vì ngủ một khoảng thời gian cố định, hãy chờ đợi điều kiện cụ thể. WebDriverWait kết hợp với expected_conditions sẽ chặn cho đến khi phần tử bạn chỉ định có mặt, do đó việc thu thập dữ liệu bắt đầu ngay khi dữ liệu tồn tại và không sớm hơn:

python Copy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, ".quote"))
)

Ưu tiên các bộ chọn ổn định hơn là các lớp CSS đã băm: một id, một thuộc tính data-*, hoặc một thẻ ngữ nghĩa sẽ tồn tại qua một thiết kế lại mà đổi tên các lớp định kiểu. Đối với một trang mà bạn phân trang, hãy đọc href của liên kết "tiếp theo" và theo dõi nó thay vì đoán số trang.

Nhận khóa API của bạn trên gói miễn phí: app.scrapeless.com

Giới hạn chân thành, và sự chuyển hướng

Selenium render JavaScript rất tốt; điều mà nó không làm được là khiến việc chạy trình duyệt rẻ hơn hoặc giữ cho lưu lượng truy cập của bạn không nổi bật. Mỗi worker Selenium là một Chrome đầy đủ, vì vậy việc mở rộng ra nhiều trang có nghĩa là mở rộng các trình duyệt và bộ nhớ mà chúng cần, và mỗi yêu cầu xuất phát từ IP của bạn, mà một trang web bận rộn có thể hạn chế tỷ lệ hoặc thách thức. Selenium không có câu trả lời tích hợp cho một thử thách chống bot đã được quản lý — nó render trang mà nó nhận được, và một trang mà nó không bao giờ đến được render thành không có gì.

Scrapeless Universal Scraping API gỡ bỏ nửa hoạt động đó khỏi máy của bạn. Bạn gửi URL với js_render được bật; nó render trang phía máy chủ với việc xử lý chống bot đã quản lý và đường ra dân cư xoay vòng, và trả lại HTML hoàn thiện trong trường data của nó. Không có trình duyệt nào để bạn khởi chạy, và yêu cầu không đến từ IP của bạn. Bạn phân tích HTML trả về chính xác như bạn sẽ phân tích mã nguồn trang của Selenium:

python Copy
import os, re, json, requests

resp = requests.post(
    "https://api.scrapeless.com/api/v2/unlocker/request",
    headers={"x-api-token": os.environ["SCRAPELESS_API_KEY"], "Content-Type": "application/json"},
    json={"actor": "unlocker.webunlocker", "input": {"url": "https://quotes.toscrape.com/js/", "js_render": True}},
    timeout=120,
)
resp.raise_for_status()
html = resp.json()["data"]

authors = re.findall(r'<small class="author">(.*?)</small>', html)
print("số khối trích dẫn đã render qua Universal Scraping API:", html.count('class="quote"'))
print("tác giả đã trích xuất:", len(authors))
print("tác giả đầu tiên:", authors[0])

Yêu cầu đơn lẻ trả về cùng một trang đã render, phía máy chủ:

text Copy
số khối trích dẫn đã render qua Universal Scraping API: 10
tác giả đã trích xuất: 10
tác giả đầu tiên: Albert Einstein

Nguyên tắc chung: giữ Selenium khi bạn kiểm soát mục tiêu và lưu lượng nhỏ, và chuyển việc lấy dữ liệu sang API khi công việc là các hoạt động — nhiều trang, IP bị chặn, hoặc một thử thách Selenium không thể vượt qua. Mã phân tích không thay đổi; chỉ nguồn HTML thì khác.

Khắc phục sự cố

Lỗi phiên bản driver gần như luôn có nghĩa là Chrome đã được cập nhật và một driver cũ còn sót lại; trên Selenium 4.6 và các phiên bản mới hơn, Selenium Manager giúp bạn xác định driver hiện tại, vì vậy việc loại bỏ ChromeDriver đã được gắn tay từ PATH của bạn thường giải quyết được vấn đề. Một kết quả trống trên một trang mà bạn có thể thấy trong một trình duyệt bình thường có nghĩa là nội dung đã đến sau khi driver.get trả về — thêm WebDriverWait ở trên cho bộ chọn mà bạn cần. Một phiên chạy treo trên một trang mà không bao giờ tắt mạng có nghĩa là bạn đã chờ điều kiện sai; hãy chờ cho phần tử, không phải cho mạng.

Giữ công việc bên trong giới hạn được nêu của một trang web. Đọc các điều khoản và tập tin Giao thức Loại trừ Robot của nó, chỉ yêu cầu các trang công cộng, và giữ độ đồng thời ở mức độ vừa phải — cùng một kỷ luật đã được đề cập trong hướng dẫn về Mô hình Đối tượng Tài liệu mà Selenium đọc. Để có một tour khám phá và lấy dữ liệu rộng hơn, hướng dẫn về xây dựng một web scraper từ đầu kết hợp tốt với cái này.

Kết luận

Selenium kiếm được vị trí của nó khi một trang cần một trình duyệt thực để tồn tại: nó điều khiển Chrome thông qua giao thức WebDriver, chạy các tập lệnh, và đưa cho bạn DOM đã render — mười câu trích dẫn từ một trang mà không chuyển tải bất kỳ thứ gì trong mã của nó. Nơi mà nó không còn có lợi là các hoạt động xung quanh trình duyệt đó: bộ nhớ khi mở rộng các phiên, sự phơi bày của IP của bạn, và những thử thách mà nó không thể vượt qua. Tại thời điểm đó, cùng một URL thông qua Scrapeless Universal Scraping API trả về HTML đã render mà không cần chạy trình duyệt, và việc phân tích của bạn vẫn giữ nguyên. Kiểm tra khối lượng yêu cầu mà bạn cần so với trang giá cả trước khi bạn mở rộng.
Tham gia cộng đồng của chúng tôi để nhận kế hoạch miễn phí và so sánh ghi chú với các nhà phát triển khác đang xây dựng scraper: Discord · Telegram.

Câu hỏi thường gặp

H: Tôi có cần tải xuống ChromeDriver để sử dụng Selenium không?

Không. Selenium 4.6 và mới hơn tích hợp Selenium Manager, tự động phát hiện Chrome đã cài đặt và giải quyết ChromeDriver tương ứng khi sử dụng lần đầu, do đó webdriver.Chrome(options=...) hoạt động mà không cần tải xuống driver thủ công.

H: Tại sao Selenium tìm thấy các phần tử mà requests không thể?

Selenium chạy trong một trình duyệt thực thi JavaScript của trang và xây dựng DOM, vì vậy các phần tử được tạo ra bởi script đã tồn tại vào thời điểm bạn truy vấn chúng. Một client HTTP thuần túy chỉ nhận được mã HTML ban đầu từ máy chủ, mà trong một trang được render bởi client thì không chứa bất kỳ nội dung nào trong số đó.

H: Khi nào tôi nên chuyển từ Selenium sang API Scraping Đa năng?

Chuyển sang khi khó khăn là về điều hành hơn là render - nhiều trang cần lấy, IP của bạn bị giới hạn tốc độ, hoặc một thử thách chống bot được quản lý mà Selenium không thể vượt qua. API thực hiện việc render phía máy chủ và trả về HTML hoàn chỉnh, nên bạn giữ lại việc phân tích và loại bỏ đội ngũ trình duyệt.

H: Làm thế nào để tôi đợi nội dung tải sau trang?

Sử dụng WebDriverWait với expected_conditions để chặn cho đến khi một selector cụ thể có mặt, thay vì sử dụng time.sleep cố định. Việc scraping bắt đầu ngay khi phần tử tồn tại, điều này nhanh hơn và đáng tin cậy hơn so với một độ trễ được đoán.

H: Việc scraping với Selenium có hợp pháp không?

Scraping dữ liệu công khai thường là được phép, nhưng trách nhiệm là của bạn: tôn trọng điều khoản của trang web và các chỉ thị robots của nó, chỉ thu thập các trang công khai, tránh dữ liệu cá nhân mà bạn không có cơ sở để xử lý, và giữ tỷ lệ yêu cầu ở mức hợp lý.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục