Selenium là một khung tự động hóa web mã nguồn mở phổ biến, chủ yếu được sử dụng để tự động hóa kiểm thử trình duyệt. Bên cạnh đó, nó cũng có thể được sử dụng để giải quyết các vấn đề scraping web động.
Selenium có 3 thành phần chính:
Browserless là gì?
Nstbrowserless là dịch vụ headlesschrome dựa trên đám mây thực hiện các thao tác web và chạy các kịch bản tự động mà không cần giao diện đồ họa. Nó đặc biệt hữu ích cho việc tự động hóa các tác vụ như web scraping và các quy trình tự động khác.
Browserless có tốt cho web scraping không?
Có, hoàn toàn! Nstbrowserless có thể thực hiện web scraping phức tạp và bất kỳ nhiệm vụ tự động hóa nào khác trên đám mây. Nó sẽ giải phóng dịch vụ và bộ nhớ cục bộ của thiết bị của bạn. Nstbrowserless hoạt động với một trình duyệt chống phát hiện và tính năng headlesschrome. Bạn không còn phải lo lắng về việc bị phát hiện và đối mặt với việc chặn web.
Kết hợp Browserless và Selenium cải thiện tự động hóa web bằng cách cho phép Selenium chạy các kịch bản kiểm tra trong một môi trường headlesschrome dựa trên đám mây do Browserless cung cấp. Cài đặt này rất hiệu quả cho các nhiệm vụ quy mô lớn như web scraping, vì nó loại bỏ nhu cầu về một trình duyệt vật lý trong khi vẫn xử lý nội dung động và tương tác của người dùng.
Bạn có những ý tưởng tuyệt vời và nghi ngờ gì về web scraping và Browserless không?
Hãy xem những gì các nhà phát triển khác đang chia sẻ trên Discord và Telegram!
Bằng cách sử dụng Node.js trong Selenium, các nhà phát triển có thể điều khiển headlesschrome để thực hiện nhiều thao tác khác nhau, chẳng hạn như web scraping, kiểm tra tự động, tạo ảnh chụp màn hình, v.v.
Sự kết hợp này tận dụng các tính năng hiệu quả, không chặn của Node.js và các khả năng của trình duyệt headlesschrome để đạt được tự động hóa và xử lý dữ liệu hiệu quả.
Nhập lệnh sau vào terminal:
npm install selenium-webdriver
Nếu terminal báo lỗi, hãy kiểm tra xem máy tính của bạn có môi trường node không:
node --version
Bạn không có môi trường node? Vui lòng cài đặt phiên bản mới nhất của môi trường node trước tiên.
Selenium nổi tiếng với khả năng tự động hóa trình duyệt mạnh mẽ. Nó hỗ trợ hầu hết các trình duyệt chính, bao gồm Chrome, Firefox, Edge, Opera, Safari và Internet Explorer.
Vì Chrome là trình duyệt phổ biến và mạnh mẽ nhất trong số đó, bạn sẽ sử dụng nó trong hướng dẫn này.
import { Builder, Browser } from 'selenium-webdriver';
async function run() {
const driver = new Builder()
.forBrowser(Browser.CHROME)
.build();
await driver.get('https://www.yahoo.com/');
}
Bạn cũng có thể thêm bất kỳ tùy chỉnh nào bạn muốn. Hãy làm cho các kịch bản của chúng ta trở thành headlesschrome:
import { Builder, Browser } from 'selenium-webdriver';
import chrome from 'selenium-webdriver/chrome';
const options = new chrome.Options();
options.addArguments('--remote-allow-origins=*');
options.addArguments('--headless');
async function run() {
const driver = new Builder()
.setChromeOptions(options)
.forBrowser(Browser.CHROME)
.build();
await driver.get('https://www.yahoo.com/');
}
Bây giờ, bạn có thể truy cập bất kỳ trang web nào!
Khi bạn có HTML hoàn chỉnh của trang web, bạn có thể tiến hành trích xuất dữ liệu cần thiết. Trong trường hợp này, chúng ta sẽ phân tích tiêu đề và nội dung của tất cả các tin tức trên trang.
Để thực hiện nhiệm vụ này, bạn phải làm theo các bước sau:
DevTools là một công cụ vô giá trong việc web scraping. Nó giúp bạn kiểm tra HTML, CSS và JavaScript hiện tại đã được tải. Bạn cũng có thể nhận thông tin về các yêu cầu mạng đã được thực hiện đến trang và thời gian tải tương ứng của chúng.
Các bộ chọn CSS và biểu thức XPath là các chiến lược lựa chọn nút đáng tin cậy nhất. Bạn có thể sử dụng bất kỳ cái nào trong số chúng để xác định các phần tử, nhưng trong hướng dẫn này, vì đơn giản, chúng ta sẽ sử dụng các bộ chọn CSS.
Hãy sử dụng DevTools để tìm bộ chọn CSS chính xác. Mở trang web mục tiêu trong trình duyệt của bạn và nhấp chuột phải vào phần tử sản phẩm > Kiểm tra để mở DevTools.

Bạn có thể thấy rằng cấu trúc của mỗi tiêu đề tin tức được tạo thành từ thẻ h3 và thẻ a, và chúng ta có thể sử dụng bộ chọn h3[data-test-locator="stream-item-title"] để xác định chúng.
Chúng ta sử dụng cùng một phương pháp để tìm bộ chọn p[data-test-locator="stream-item-summary"] cho nội dung tin tức.
Xác định bộ chọn CSS bằng cách sử dụng thông tin trên và xác định sản phẩm bằng cách sử dụng các phương pháp findElements() và findElement().
Ngoài ra, hãy sử dụng phương pháp getText() để trích xuất văn bản bên trong của nút HTML, và cuối cùng lưu trữ tên và giá trị đã trích xuất vào một mảng.
const titlesArray = [];
const contentArray = [];
const newsTitles = await driver.findElements(By.css('
h3[data-test-locator="stream-item-title"]'));
const newsContents = await driver.findElements(By.css('p[data-test-locator="stream-item-summary"]'));
for (let title of newsTitles) {
titlesArray.push(await title.getText());
}
for (let content of newsContents) {
contentArray.push(await content.getText());
}
Chúng ta đã thu thập được dữ liệu web scraping! Bây giờ, chúng ta cần xuất chúng ra một tệp CSV.
Nhập mô-đun fs tích hợp sẵn của Node.js, cung cấp các chức năng để làm việc với hệ thống tệp:
import fs from 'node';
Sau đó, khởi tạo một biến chuỗi gọi là newsData với một hàng tiêu đề chứa các tên cột ("title, content\n").
let newsData = 'title,content\n';
Tiếp theo, lặp qua hai mảng (titlesArray và contentsArray) chứa tiêu đề và nội dung tin tức. Đối với mỗi phần tử trong mảng, hãy thêm một dòng vào sau newsData với một dấu phẩy phân tách tiêu đề và nội dung.
for (let i = 0; i < titlesArray.length; i++) {
newsData += `${titlesArray[i]},${contentsArray[i]}\n`;
}
Sử dụng hàm fs.writeFile() để ghi chuỗi newsData vào một tệp có tên yahooNews.csv. Hàm này chấp nhận ba tham số: tên tệp, dữ liệu cần ghi, và một hàm gọi lại để xử lý bất kỳ lỗi nào xảy ra trong quá trình ghi.
fs.writeFile("yahooNews.csv", newsData, err => {
if (err) {
console.error("Lỗi:", err);
} else {
console.log("Thành công!");
}
});
Chạy mã của chúng tôi, bạn sẽ nhận được kết quả tương tự như sau:

Chúc mừng, bạn đã học cách sử dụng Selenium và headlesschrome: NodeJS để crawl dữ liệu.
Sử dụng chế độ headlesschrome trong Browserless có thể tự động tránh phát hiện và chặn web đến mức tối đa. Nhưng hãy kết hợp những chiến lược sau để có được trải nghiệm crawl hiệu quả và liền mạch hơn.
Dưới đây là mã mẫu sử dụng Selenium và Node.js để mô phỏng hành vi người dùng thực. Mã này cho thấy cách đặt User-Agent, mô phỏng các thao tác chuột, xử lý nội dung động, mô phỏng đầu vào từ bàn phím, và kiểm soát hành vi trình duyệt.
Trước khi sử dụng, hãy chắc chắn rằng bạn đã cài đặt selenium-webdriver và chromedriver.
const { Builder, By, Key, until } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('path');
// Khởi động trình duyệt
(async function example() {
// Cấu hình tùy chọn Chrome
let chromeOptions = new chrome.Options();
chromeOptions.addArguments('headless'); // Sử dụng chế độ headless
chromeOptions.addArguments('window-size=1280,800'); // Đặt kích thước cửa sổ trình duyệt
// Tạo một instance WebDriver
let driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(chromeOptions)
.build();
try {
// Đặt User-Agent và các tiêu đề yêu cầu khác
await driver.executeCdpCmd('Network.setUserAgentOverride', {
userAgent: 'User-Agent Tùy Chỉnh Của Bạn',
});
// Điều hướng đến trang mục tiêu
await driver.get('https://example.com');
// Mô phỏng di chuyển chuột và nhấp chuột
let element = await driver.findElement(By.css('selector-for-clickable-element'));
await driver.actions().move({ origin: element }).click().perform();
// Thời gian chờ ngẫu nhiên
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
await sleep(Math.random() * 5000 + 2000); // Chờ ngẫu nhiên từ 2 đến 7 giây
// Xử lý nội dung động và chờ một phần tử cụ thể tải
await driver.wait(until.elementLocated(By.css('#dynamic-content')), 10000);
// Mô phỏng đầu vào từ bàn phím
let searchInput = await driver.findElement(By.css('#search-input'));
await searchInput.sendKeys('Node.js', Key.RETURN);
// Cuộn ngẫu nhiên
await driver.executeScript('window.scrollBy(0, window.innerHeight);');
} finally {
// Đóng trình duyệt
await driver.quit();
}
})();
Sử dụng máy chủ proxy để ẩn địa chỉ IP thực của bạn có thể hiệu quả trong việc tránh bị chặn IP. Bạn có thể chọn quay vòng proxy để sử dụng địa chỉ IP khác cho mỗi yêu cầu để giảm nguy cơ bị chặn.
Kiểm soát tần suất crawling để tránh gửi một số lượng lớn yêu cầu trong một khoảng thời gian ngắn, điều này có thể giảm nguy cơ kích hoạt các cơ chế chống crawler. Bạn có thể đặt một khoảng thời gian phù hợp để gửi yêu cầu để mô phỏng hành vi duyệt web bình thường.
Nếu trang web sử dụng CAPTCHA để bảo vệ, bạn có thể sử dụng dịch vụ nhận diện CAPTCHA bên thứ ba để tự động giải quyết các thách thức này, hoặc cấu hình Selenium để xử lý CAPTCHA.
Một số trang web sử dụng dấu vân tay trình duyệt để nhận diện các công cụ tự động. Cấu hình các dấu vân tay trình duyệt khác nhau hoặc sử dụng một trình duyệt chống phát hiện với tính năng chuyển đổi dấu vân tay tích hợp có thể giúp vượt qua các phát hiện của trang web.
Sử dụng Browserless kết hợp với Selenium để xử lý nội dung tải động (chẳng hạn như các yêu cầu AJAX) có thể đảm bảo rằng tất cả dữ liệu được kết xuất động trên trang web được ghi lại, không chỉ là nội dung tĩnh.
Selenium cung cấp nhiều phương pháp để tìm các phần tử trên trang, bao gồm:
<input> hoặc <button>, phù hợp cho các tìm kiếm rộng..class-name, phù hợp để nhanh chóng xác định các phần tử có tên lớp cụ thể.#element-id, đặc biệt hiệu quả để nhanh chóng và chính xác tìm các phần tử cụ thể.> p.class-name.//div[@id='example'].Vì vậy, trong Selenium WebDriver, chúng ta có thể xác định các phần tử trên một trang web thông qua phương thức find_element. Bạn chỉ cần thêm các yêu cầu cụ thể khi sử dụng nó. Ví dụ:
find_element_by_id: Tìm một phần tử theo ID duy nhất của nó.find_element_by_class_name: Tìm một phần tử theo tên lớp CSS của nó.find_element_by_link_text: Tìm một phần tử liên kết theo văn bản liên kết của nó.Trong một số tình huống, chẳng hạn như mạng chậm hoặc trình duyệt, mã của bạn có thể gặp lỗi hoặc hiển thị kết quả không nhất quán.
Thay vì chờ một khoảng thời gian cố định, hãy chọn chờ một cách thông minh, chẳng hạn như chờ một phần tử cụ thể xuất hiện hoặc hiển thị trên trang. Điều này đảm bảo rằng các phần tử web đã được tải đầy đủ trước khi tương tác với chúng, giảm nguy cơ lỗi như element not found và element not interactable.
Đoạn mã sau thực hiện chiến lược chờ. Phương thức until.elementsLocated xác định điều kiện chờ, đảm bảo WebDriver chờ đến khi phần tử được chỉ định được tìm thấy hoặc thời gian chờ tối đa là 5000 mili giây (5 giây) được đạt đến.
const { Builder, By, until } = require('selenium-webdriver');
const yourElements = await driver.wait(until.elementsLocated(By.css('.your
-css-selector')), 5000);
Trong NodeJS, bạn có thể chụp ảnh màn hình chỉ bằng cách gọi một hàm. Tuy nhiên, có một số cân nhắc để đảm bảo rằng các ảnh chụp màn hình được ghi lại chính xác:
import fs from 'node';
import { Builder, Browser } from 'selenium-webdriver';
async function screenshot() {
const driver = new Builder()
.forBrowser(Browser.CHROME)
.build();
await driver.get('https://www.yahoo.com/');
const pictureData = await driver.takeScreenshot();
fs.writeFileSync('screenshot.png', pictureData, 'base64');
}
screenshot();
Có cách dễ hơn để thực hiện tất cả các nhiệm vụ chuyên biệt không? Tất nhiên là có! Nstbrowser cung cấp các dịch vụ RPA hoàn toàn miễn phí. Bằng cách chỉ cần cấu hình quy trình làm việc bạn cần, bạn có thể dễ dàng thực hiện tất cả các yêu cầu crawling.
Lấy Dữ Liệu Phần Tử
Chờ Yêu Cầu
Chụp Ảnh Màn Hình
Một trong những tính năng nổi bật khi sử dụng công cụ tự động hóa trình duyệt như Selenium là khả năng tận dụng công cụ JavaScript của trình duyệt. Điều này có nghĩa là bạn có thể chèn và thực thi mã JavaScript tùy chỉnh trong ngữ cảnh của trang web mà bạn đang tương tác.
const javascript = 'window.scrollBy(100, 100)';
await driver.executeScript(javascript);
Trong hướng dẫn Selenium Node.js này, bạn đã học cách sử dụng headlesschrome với Selenium để thiết lập một dự án Node.js WebDriver, thu thập dữ liệu từ các trang web động, tương tác với nội dung động, và xử lý các thách thức web scraping phổ biến.
Bây giờ là thời điểm tốt để xây dựng quy trình web scraping của riêng bạn! Với sự hỗ trợ của Nstbrowser RPA, mọi thứ phức tạp sẽ được đơn giản hóa.