NODRIVER là công cụ tự động hóa trình duyệt dựa trên Python. Nó cho phép mở các trang web, tương tác và thu thập dữ liệu thông qua mã code. NODRIVER không phụ thuộc vào Selenium hoặc Puppeteer. Nó cũng không sử dụng ChromeDriver. Thay vào đó, nó sử dụng phương pháp riêng để kiểm soát trình duyệt.
Điều này mang lại một số lợi thế quan trọng:
- Nó tránh bị phát hiện tốt hơn các công cụ truyền thống.
- Nó yêu cầu ít thiết lập hơn.
- Nó hỗ trợ lập trình bất đồng bộ (async) hiện đại.
Cải thiện Trích xuất Dữ liệu với Máy chủ MCP
Nếu cần giải pháp đơn giản và rẻ cho việc trích xuất web quy mô lớn hoặc phức tạp, hãy cân nhắc sử dụng Giao thức Ngữ cảnh Mô hình (MCP) của Bright Data. Điều này bao gồm các trang web có CAPTCHA hoặc bảo vệ chống bot nâng cao.
Tôi không có liên kết với Bright Data. Tôi chỉ thực sự thích sử dụng máy chủ MCP của họ. Máy chủ MCP của Bright Data cung cấp quyền truy cập vào TẤT CẢ các sản phẩm của họ từ một nơi duy nhất.
Hãy kiểm tra tất cả các công cụ có sẵn như Selenium, Playwright và Puppeteer đã có mặt. Bây giờ, chúng ta quay lại với NODRIVER.
Tại sao nên Sử dụng NODRIVER cho Web Scraping?
Nhiều công cụ như Selenium, Playwright và Puppeteer đã tồn tại.
Vậy tại sao các doanh nghiệp nên cân nhắc NODRIVER?
- Không cần Trình điều khiển bên ngoài: Các công cụ truyền thống như Selenium cần ChromeDriver.Việc cài đặt và cập nhật ChromeDriver có thể gây khó chịu.NODRIVER không cần bất kỳ trình điều khiển nào.Bạn chỉ cần Python và một trình duyệt dựa trên Chrome (như Chrome hoặc Brave).
- Thiết lập Đơn giản: Cài đặt NODRIVER chỉ cần một lệnh duy nhất:
pip install nodriver
Không cần thiết lập bổ sung nào khác. Tạo virtual environment (khuyến nghị) để tránh xung đột thư viện:
python3 -m venv venv_nodriver
source venv_nodriver/bin/activate
Bạn không phải xử lý các đường dẫn phức tạp hoặc biến hệ thống. - Thiết kế Bất đồng bộHầu hết các thư viện trích xuất dữ liệu đều đồng bộ.Điều này có nghĩa là chúng chạy từng tác vụ một.NODRIVER sử dụng các hàm bất đồng bộ (async functions).Điều này cho phép thực hiện nhiều việc hơn trong thời gian ngắn hơn.Nó hoàn hảo cho việc trích xuất nhiều trang cùng một lúc.
- Tránh Phát hiện Tốt hơnCác trang web ngày càng thông minh hơn trong việc phát hiện bot.NODRIVER không tuân theo các mẫu giống như Selenium hoặc Puppeteer.Do đó, nó có thể tránh bị phát hiện trong một số trường hợp.
Thiết lập Script NODRIVER đầu tiên
Đây là các bước để trích xuất dữ liệu từ một trang web đơn giản bằng NODRIVER.
Bước 1: Cài đặt NODRIVER
Mở terminal và chạy lệnh:
pip install nodriver
Đảm bảo bạn đã cài đặt Python 3.7+.
Bước 2: Viết Script Cơ bản
Phiên bản của nodriver mà đang dùng (ví dụ pip show nodriver
cho ra "Version: x.y.z"
. Ví dụphiên bản 0.47.0. Dưới đây là bản script Python đã chỉnh sửa đúng API (theo tài liệu cho phiên bản đó) và phù hợp với cấu trúc bạn muốn:
import nodriver as uc
import asyncio
async def main():
# Khởi trình duyệt với các tham số cần nếu cần (headless, no sandbox,…)
browser = await uc.start(headless=True, sandbox=False, args=[
“–no-sandbox”,
“–disable-dev-shm-usage”,
“–disable-gpu”
])
try:
page = await browser.get(“//quotes.toscrape.com”)
quotes = await page.select_all(“div.quote”)
for quote in quotes:
text_elem = await quote.query_selector(“span.text”)
author_elem = await quote.query_selector(“small.author”)
text = text_elem.text if text_elem else None
author = author_elem.text if author_elem else None
print(f”{text} – {author}”)
await page.close()
except Exception as e:
print(“Lỗi:”, e)
finally:
# Đóng browser — theo tài liệu cho phiên bản này dùng browser.close()
try:
await browser.close()
except Exception:
pass
if __name__ == ‘__main__’:
uc.loop().run_until_complete(main())
Script này mở trình duyệt, truy cập trang web //example.com
, sau đó đóng trình duyệt.
Điều hướng Trang và Thu thập Dữ liệu
Bây giờ chúng ta sẽ đi sâu hơn vào cách thu thập dữ liệu thực tế.
Ví dụ: Trích xuất Trích dẫn từ một Trang Web
Giả sử bạn muốn thu thập các trích dẫn từ trang web //quotes.toscrape.com
.
Trang này được tạo ra để thực hành trích xuất dữ liệu.
Đây là cách thu thập tất cả các trích dẫn trên một trang:
import nodriver
async def main():
browser = await nodriver.start()
page = await browser.get("//quotes.toscrape.com")
quotes = await page.select_all("div.quote")
for quote in quotes:
text = (await quote.query_selector("span.text")).text
author = (await quote.query_selector("small.author")).text
print(f"{text} - {author}")
await page.close()
if __name__ == '__main__':
nodriver.loop().run_until_complete(main())
Xử lý Nhiều Trang (Phân trang)
Nhiều trang web chia dữ liệu thành nhiều trang riêng biệt.
Đây được gọi là phân trang.
Để xử lý điều này, bạn cần phát hiện nút “Next”.
Bạn phải tiếp tục truy cập các trang mới cho đến khi nút “Next” biến mất.
Đây là cách thực hiện:
import nodriver
async def main():
browser = await nodriver.start()
base_url = "//quotes.toscrape.com"
next_url = "/"
while next_url:
page = await browser.get(base_url + next_url)
quotes = await page.select_all("div.quote")
for quote in quotes:
text = (await quote.query_selector("span.text")).text
author = (await quote.query_selector("small.author")).text
print(f"{text} - {author}")
next_btn = await page.select("li.next > a")
if next_btn:
attrs = next_btn.attributes
for i in range(len(attrs)):
if attrs[i] == "href":
next_url = attrs[i+1]
break
else:
next_url = None
await page.close()
if __name__ == '__main__':
nodriver.loop().run_until_complete(main())
Phiên bản này đi qua tất cả các trang và in ra mọi trích dẫn tìm thấy.
Trích xuất và Lưu trữ Dữ liệu
Bạn có thể lưu dữ liệu vào một tệp thay vì chỉ in ra.
JSON là một định dạng tốt cho việc lưu trữ dữ liệu có cấu trúc.
Đây là cách lưu các trích dẫn đã trích xuất vào tệp JSON:
import nodriver
import json
async def main():
browser = await nodriver.start()
base_url = "//quotes.toscrape.com"
next_url = "/"
data = []
while next_url:
page = await browser.get(base_url + next_url)
quotes = await page.select_all("div.quote")
for quote in quotes:
text = (await quote.query_selector("span.text")).text
author = (await quote.query_selector("small.author")).text
tags = [tag.text for tag in await quote.query_selector_all("a.tag")]
data.append({
"quote": text,
"author": author,
"tags": tags
})
next_btn = await page.select("li.next > a")
if next_btn:
attrs = next_btn.attributes
for i in range(len(attrs)):
if attrs[i] == "href":
next_url = attrs[i+1]
break
else:
next_url = None
await page.close()
with open("quotes.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
if __name__ == '__main__':
nodriver.loop().run_until_complete(main())
Sau khi chạy script, bạn sẽ nhận được tệp quotes.json
chứa tất cả nội dung đã trích xuất.
Những Thách thức Hiện tại với NODRIVER
NODRIVER là một công cụ mới.
Điều này đồng nghĩa với việc có một số lỗi và thiếu sót tính năng.
- Chế độ Không đầu (Headless Mode) có thể không hoạt độngChạy NODRIVER mà không hiển thị trình duyệt đôi khi bị lỗi.Đây có thể là một lỗi hoặc một tính năng để tránh phát hiện bot.
- Trích xuất Thuộc tính không mượt màKhi lấy thuộc tính của một phần tử, NODRIVER trả về một danh sách (list) thay vì một từ điển.Điều này làm cho việc xử lý trở nên khó khăn.Ví dụ,
attrs = element.attributes
trả về[‘href’, ‘/page/2/’]
.Người dùng phải lặp qua danh sách này để tìm thuộc tính cần thiết. - Hỗ trợ Proxy Hạn chếSử dụng proxy là cần thiết cho việc trích xuất dữ liệu nghiêm túc.NODRIVER có phương thức
create_context()
.Tuy nhiên, tài liệu hướng dẫn không đầy đủ.Hiện tại, tính năng này hoạt động không ổn định.Nó có thể hoạt động tốt hơn trong tương lai.
Các Trường hợp Sử dụng Tốt cho NODRIVER
NODRIVER rất phù hợp cho các mục đích sau:
- Học cách trích xuất dữ liệu bất đồng bộ.
- Tránh các cơ chế phát hiện bot đơn giản.
- Trích xuất dữ liệu từ các trang web nhỏ hơn.
- Kiểm tra ý tưởng nhanh chóng.
Nếu dự án phức tạp liên quan đến quy trình đăng nhập, CAPTCHA, hoặc cấm IP, bạn vẫn cần Selenium hoặc Playwright.
Các Công cụ Thay thế cho NODRIVER
Nếu NODRIVER không đáp ứng nhu cầu, đây là các công cụ vững chắc khác:
- PlaywrightHoàn toàn bất đồng bộ.Hỗ trợ chế độ không đầu.Hỗ trợ tích hợp sẵn cho việc chờ đợi, xác thực và tải xuống tệp.
- SeleniumRất trưởng thành và ổn định.Hỗ trợ nhiều trình duyệt.Có cộng đồng lớn và nhiều hướng dẫn.
- ScrapyTốt nhất cho việc trích xuất dữ liệu quy mô lớn.Hoạt động với bộ chọn (selectors) và pipelines.Được xây dựng để thu thập dữ liệu từ nhiều trang và lưu trữ.
Tương lai của NODRIVER
NODRIVER vẫn đang phát triển.
Nhà phát triển của nó cũng là người tạo ra Undetected Chromedriver.
Undetected Chromedriver nổi tiếng vì khả năng tránh phát hiện bot.
Kinh nghiệm này cho thấy NODRIVER sẽ ổn định hơn theo thời gian.
Các tính năng dự kiến sớm xuất hiện bao gồm:
- Xử lý thuộc tính tốt hơn.
- Hỗ trợ proxy đầy đủ.
- Cải thiện tương tác trang như nhấp chuột và gõ phím.
- Chế độ không đầu hoạt động ổn định.
Kết luận
Trích xuất web vào năm 2025 nhanh hơn và dễ dàng hơn với các công cụ như NODRIVER.
Nó cho phép xây dựng các trình trích xuất đơn giản và nhanh chóng với thiết lập tối thiểu.
NODRIVER nhẹ và dễ sử dụng.
Nó hoạt động mà không cần Selenium hoặc Puppeteer.
Điều này làm cho nó tuyệt vời cho các dự án nhỏ hoặc học tập trích xuất bất đồng bộ.
Tuy nhiên, nó vẫn có một số lỗi và hạn chế.
Nó chưa hoàn toàn hỗ trợ proxy, CAPTCHA, hoặc chế độ không đầu.
Đối với các nhu cầu nâng cao hơn, các công cụ như Playwright hoặc Selenium là lựa chọn tốt hơn.
Nếu bạn muốn kiểm tra ý tưởng nhanh chóng, NODRIVER là một lựa chọn tuyệt vời.
Đây là một trong những công cụ trích xuất dữ liệu thú vị nhất hiện nay.
Tham khảo: medium.com
n8n không chạy Python, nên bạn có thể:
Gọi script Python này bằng Execute Command Node trong n8n.
Hoặc dùng Webhook để n8n gọi API do Python (chạy nodriver) cung cấp.
Kết quả (HTML, ảnh, dữ liệu) có thể đẩy ngược lại n8n để xử lý tiếp.
[HTTP Trigger] → [Execute Command: python3 scraper.py] → [Set / Transform data] → [Send Telegram]Tránh dùng trình duyệt giúp workflow chạy nhanh hơn và ổn định hơn (đặc biệt trên máy yếu như Orange Pi).
Chạy lệnh như: python3 scraper.py //quotes.toscrape.com
import nodriver as uc
import asyncio
import sys
import json
async def main():
if len(sys.argv) < 2:
print(“Usage: python3 scraper.py <URL>”)
return
url = sys.argv[1].strip()
if not (url.startswith(“//”) or url.startswith(“//”)):
print(“URL không hợp lệ, vui lòng nhập đường dẫn dạng // hoặc //”)
return
# Khởi trình duyệt
browser = await uc.start(headless=True, sandbox=False, args=[
“–no-sandbox”,
“–disable-dev-shm-usage”,
“–disable-gpu”
])
try:
page = await browser.get(url)
quotes = await page.select_all(“div.quote”)
for quote in quotes:
text_elem = await quote.query_selector(“span.text”)
author_elem = await quote.query_selector(“small.author”)
text = text_elem.text if text_elem else None
author = author_elem.text if author_elem else None
print(f”{text} — {author}”)
await page.close()
except Exception as e:
print(“Có lỗi xảy ra:”, e)
finally:
try:
await browser.close()
except Exception:
pass
if __name__ == ‘__main__’:
uc.loop().run_until_complete(main())
Script sẽ mở browser headless, truy cập URL, tìm các phần tử
div.quote
, in mỗi câu trích dẫn + tác giả ra terminal.Sau khi hoàn tất, browser sẽ đóng lại.
Bài viết liên quan: