Nstbrowser hiện hỗ trợ giải CAPTCHA, với 5 loại CAPTCHA.

Tìm hiểu thêm

🚀

Platform Proxy đã hoạt động trong Nstbrowser — proxy tích hợp sẵn từ$0.4/GB.

Bắt đầu ngay

  • Định giá
  • Tài liệu
VI
Liên hệ

© 2026 NST LABS TECH LTD. ALL RIGHTS RESERVED

Sản phẩm

Trình duyệt chống vân tay
Nstbrowser RPA
AI Agent Skills
Proxy
Vượt qua đám mây
Trình mở khóa web

Giải pháp

Trình duyệt chống vân tay dựa trên đám mây
Quản lý nhiều tài khoản
Rút trích nội dung trang web
Giải pháp chống bot
Cách ly dữ liệu để bảo mật doanh nghiệp
Trình kiểm tra IP Claude AI

Nguồn

Định giá
Tải xuống
Thị trường RPA
Chương trình liên kết
Đối tác
Blog
Ghi chú phát hành

Ủng hộ

Liên hệ

Tài liệu

Hợp pháp

Điều kiện
Chính sách bảo mật
Chính sách cookie

Sản phẩmGiải phápNguồnỦng hộHợp pháp

Sản phẩmGiải phápNguồn

Ủng hộHợp pháp

© 2026 NST LABS TECH LTD. ALL RIGHTS RESERVED

Quay lại Blog
thu thập dữ liệu web puppeteer
Browserless

Làm thế nào để thực hiện Web Scraping bằng Puppeteer và Node.JS?

Headlesschrome rất quan trọng trong việc thu thập dữ liệu web. Bài viết này sẽ nói về các bước chi tiết nhất để thực hiện thu thập dữ liệu web bằng headlesschrome và Puppeteer.
Aug 09, 2024Tạ Quí Lĩnh

Headlesschrome là gì?

Headless? Đúng vậy, điều đó có nghĩa là trình duyệt này không có giao diện người dùng đồ họa (GUI). Thay vì sử dụng chuột hoặc thiết bị cảm ứng để tương tác với các yếu tố trực quan, bạn sử dụng giao diện dòng lệnh (CLI) để thực hiện tự động hóa.

Headlesschrome và Puppeteer

Nhiều công cụ web scraping có sẵn cho headlesschrome, và headlesschrome thường giúp giảm bớt rất nhiều phiền toái.

Bạn cũng có thể thích: Làm thế nào để phát hiện và chống phát hiện headlesschrome?

Puppeteer là gì? Đó là một thư viện Node.js cung cấp API cấp cao để điều khiển headlesschrome hoặc Chromium hoặc tương tác với DevTools Protocol.

Hôm nay, chúng ta sẽ khám phá headlesschrome sâu hơn với Puppeteer.

Những lợi ích của việc sử dụng Puppeteer cho Web Scraping là gì?

Như bạn có thể tưởng tượng, có nhiều lợi ích lớn khi sử dụng Puppeteer cho web scraping:

  • Các công cụ scraping của Puppeteer cho phép trích xuất dữ liệu động vì headlesschrome có thể render JavaScript, hình ảnh, v.v. giống như các trình duyệt web thông thường.
  • Các tập lệnh web scraping của Puppeteer khó bị phát hiện và chặn. Vì cấu hình kết nối giống như của một người dùng bình thường, rất khó để xác định nó là tự động hóa.

Làm thế nào để thực hiện Web Scraping với Puppeteer và Node.JS?

Trong ví dụ dưới đây, chúng ta sẽ thực hiện web scraping cơ bản để giúp bạn bắt đầu nhanh chóng với Puppeteer. Trang mà chúng tôi chọn để thu thập dữ liệu là phần đánh giá của sản phẩm Apple AirPods Pro trên Amazon.

Nhưng đừng lo, trước đó, chúng ta vẫn cần một số chuẩn bị:

Cài đặt và cấu hình Puppeteer

  • Bước 1. Vui lòng đảm bảo rằng bạn đã cài đặt Node.js.

Nếu chưa, hãy cài đặt Node.js (LST) trực tiếp, sau đó cài đặt Puppeteer thông qua trình quản lý gói npm của Node.js. Quy trình này có thể mất một chút thời gian vì Puppeteer cũng cần cài đặt Chrome tương ứng.

Bash Copy
npm i puppeteer
  • Bước 2. Sau khi cài đặt, bạn có thể chạy demo sau để đảm bảo rằng cài đặt của bạn là chính xác.

Bạn cũng có thể sử dụng demo này để hiểu tổng quan về Puppeteer. Đừng mắc kẹt ở đây, vì chúng tôi sẽ giới thiệu chi tiết về cách sử dụng Puppeteer và các kịch bản liên quan sau đó.

Puppeteer mặc định được bật chế độ headless. Ở đây, headless được tắt qua puppeteer.launch({ headless: false }) để bạn có thể thấy quá trình thu thập dữ liệu.

JavaScript Copy
import puppeteer from 'puppeteer';
// Khởi chạy trình duyệt và mở một tab mới
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
// Điều hướng đến một URL được chỉ định
await page.goto('https://developer.chrome.com/');
// Đặt kích thước màn hình
await page.setViewport({width: 1080, height: 1024});
// Xác định phần tử ô tìm kiếm và nhập nội dung vào ô tìm kiếm
await page.locator('.devsite-search-field').fill('automate beyond recorder');
// Chờ và nhấp vào kết quả tìm kiếm đầu tiên
await page.locator('.devsite-result-item-link').click();
// Xác định tiêu đề đầy đủ bằng cách sử dụng chuỗi duy nhất
const textSelector = await page
  .locator('text/Customize and automate')
  .waitHandle();
const fullTitle = await textSelector?.evaluate(el => el.textContent);
// In tiêu đề đầy đủ
console.log('The title of this blog post is "%s".', fullTitle);
// Đóng phiên bản trình duyệt
await browser.close();

Puppeteer là thư viện bất đồng bộ promise chạy thông qua async await, có thể trình bày các chức năng của nó rất trực quan. Demo trên và các ví dụ sau không cần các hàm async. Điều này là vì "type": "module" trong package.json được thiết lập để chạy dưới dạng ES Modules.

Phân tích Trang

Được rồi, chúng ta hãy bắt đầu.

Vui lòng mở khu vực bình luận của Apple AirPods Pro trước, và sau đó chúng ta cần xác định các phần tử mà chúng ta muốn thu thập nội dung. Bạn có thể mở Devtools bằng cách nhấn Ctrl + Shift + I (Windows/Linux) hoặc Cmd + Option + I (Mac).

mở Devtools
  • Bước 1. Nhấp vào trình chọn phần tử ở góc trên cùng bên trái của bảng điều khiển
  • Bước 2. Sử dụng chuột để di chuột qua và chọn nút phần tử bạn muốn lấy. Bảng điều khiển cũng sẽ làm nổi bật mã HTML tương ứng với phần tử này

Puppeteer hỗ trợ nhiều phương pháp chọn phần tử (puppeteer selectors), nhưng phương pháp đơn giản CSS là phương pháp được khuyến nghị nhất để bắt đầu. .devsite-search-field được sử dụng ở trên cũng là một bộ chọn CSS.

Sao chép bộ chọn

Đối với các cấu trúc CSS phức tạp, bảng điều khiển gỡ lỗi có thể sao chép trực tiếp các bộ chọn CSS. Nhấp chuột phải vào mã HTML của phần tử cần lấy để mở menu > Sao chép > Sao chép bộ chọn.

Nhưng không khuyến khích bạn làm điều này, vì các bộ chọn sao chép từ các cấu trúc phức tạp rất khó đọc và không thuận lợi cho việc bảo trì mã. Tất nhiên, điều đó hoàn toàn ổn cho một số lựa chọn đơn giản và thử nghiệm cá nhân.

Bây giờ, bộ chọn phần tử đã được xác định. Chúng ta có thể sử dụng Puppeteer để thử lấy tên người dùng tôi đã chọn ở trên.

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(
  `https://www.amazon.com/Apple-Generation-Cancelling-Transparency-Personalized/product-reviews/B0CHWRXH8B/ref=cm_cr_dp_d_show_all_btm?ie=UTF8&reviewerType=all_reviews`
);

const username = await page.$eval('div[data-hook="genome-widget"] .a-profile-name', node => node.textContent)

console.log('[username]===>', username);

Như bạn có thể thấy, mã trên sử dụng page.goto để chuyển đến trang được chỉ định. Sau đó, page.$eval có thể lấy nút phần tử đầu tiên được khớp và lấy các thuộc tính cụ thể của nút phần tử thông qua hàm callback.

Nếu bạn may mắn không kích hoạt trang xác minh của Amazon, bạn có thể lấy giá trị thành công. Tuy nhiên, một tập lệnh ổn định không thể chỉ dựa vào may mắn, vì vậy chúng ta vẫn cần thực hiện một số tối ưu hóa tiếp theo.

Chờ trang tải

Mặc dù chúng ta đã lấy được thông tin của nút phần tử thông qua phương pháp trên, chúng ta phải xem xét các yếu tố khác: chẳng hạn như tốc độ tải mạng, trang có cuộn đến phần tử mục tiêu để tải phần tử đúng cách hay không, và có phải trang xác minh bị kích hoạt và cần được xử lý thủ công hay không.

Vì vậy, trước khi quá trình tải hoàn tất, chúng ta phải kiên nhẫn chờ đợi. Tất nhiên, Puppeteer cũng cung cấp cho chúng ta các API tương ứng để sử dụng.

API thường được sử dụng waitForSelector là một API chờ phần tử xuất hiện. Chúng ta có thể sử dụng nó để tối ưu hóa mã trên để đảm bảo tính ổn định của tập lệnh. Chỉ cần sử dụng API waitForSelector trước khi gọi page.$eval.

Bằng cách này, Puppeteer sẽ chờ trang tải phần tử div[data-hook="genome-widget"] .a-profile-name trước khi thực hiện mã tiếp theo.

JavaScript Copy
await page.waitForSelector('div[data-hook="genome-widget"] .a-profile-name');
const username = await page.$eval('div[data-hook="genome-widget"] .a-profile-name', node => node.textContent)

Cũng có một số API chờ khác cho các kịch bản khác nhau. Hãy xem một số cái phổ biến:

  1. page.waitForFunction(pageFunction, options, ...args): Chờ cho hàm được chỉ định trả về true trong ngữ cảnh trang.
JavaScript Copy
import puppeteer from 'puppeteer'

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

// Chờ tiêu đề của trang thay đổi thành "Example Domain"
await page.waitForFunction('document.title === "Example Domain"');
console.log('Title has changed to "Example Domain"');

await browser.close();
  1. page.waitForNavigation(options): Chờ hoàn tất điều hướng trang. Điều hướng có thể là nhấp vào liên kết, gửi mẫu, gọi window.location, v.v.
JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

// Nhấp vào liên kết và chờ điều hướng hoàn tất
await Promise.all([
  page.click('a'),
  page.waitForNavigation()
])

console.log('Navigation complete');
await browser.close();
  1. page.waitForRequest(urlOrPredicate, options): Chờ các yêu cầu khớp với URL hoặc hàm điều kiện được chỉ định.
JavaScript Copy
import puppeteer from "puppeteer";

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example.com');

// Yêu cầu bạn theo dõi URL yêu cầu thực tế của trang. Đây chỉ là ví dụ.
// Nhưng bạn có thể nhập https://example.com/resolve vào thanh địa chỉ của trình duyệt để kích hoạt yêu cầu và xác minh demo này
const Request = await page.waitForRequest('https://example.com/resolve');

console.log('request-url:', Request.url());
await browser.close()
  1. page.waitForResponse(urlOrPredicate, options): Chờ phản hồi khớp với URL hoặc hàm điều kiện được chỉ định.
JavaScript Copy
import puppeteer from "puppeteer";

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://example.com');

// Phản hồi yêu cầu bạn theo dõi URL phản hồi thực tế của trang. Đây chỉ là ví dụ.
// Nhưng bạn có thể nhập https://example.com/resolve vào thanh địa chỉ của trình duyệt để kích hoạt phản hồi và xác minh demo này
const response = await page.waitForResponse('https://example.com/resolve');

console.log('response-status:', response.status());
await browser.close();
  1. page.waitForNetworkIdle(options): Chờ hoạt động mạng trên trang trở nên nhàn rỗi. Phương pháp này hữu ích để đảm bảo rằng trang đã hoàn tất tải.
JavaScript Copy
import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');

await page.waitForNetworkIdle({
  timeout: 30000, // Thời gian chờ tối đa 30 giây
  idleTime: 500   // Tức là không có hoạt động mạng trong vòng 500 mili giây thời gian nhàn rỗi
});

console.log('Network is idle.');

// Lưu ảnh chụp màn hình để xác minh xem trang đã được tải hoàn toàn chưa
await page.screenshot({ path: 'example.png' });
await browser.close();
  1. setTimeout: Sử dụng API Javascript trực tiếp cũng là một lựa chọn tốt. Sau khi đóng gói một chút, nó có thể được chạy trong ngữ cảnh của trang.
JavaScript Copy
// Chờ hai giây trước khi thực hiện script tiếp theo
await new Promise(resolve => setTimeout(resolve, 2000))
await page.click('.devsite-result-item-link'); // Nhấp vào phần tử này

Bạn có bất kỳ ý tưởng tuyệt vời hoặc nghi ngờ nào 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!

Thu thập và lưu trữ dữ liệu

Được rồi, hãy bắt đầu thu thập dữ liệu toàn bộ danh sách bình luận trên trang.

  • Bước 1. Thu thập dữ liệu

Chúng ta có thể viết lại đoạn mã trên để không chỉ thu thập một tên người dùng mà tập trung vào toàn bộ danh sách bình luận.

Đoạn mã sau cũng sử dụng page.waitForSelector để chờ đợi phần tử bình luận được tải và sử dụng page.$$ để lấy tất cả các nút phần tử phù hợp với bộ chọn phần tử:

JavaScript Copy
await page.waitForSelector('div[data-hook="review"]');
const reviewList = await page.$$('div[data-hook="review"]');

Tiếp theo, chúng ta cần lặp qua danh sách phần tử bình luận và lấy thông tin cần thiết từ mỗi phần tử bình luận.

Trong đoạn mã sau, chúng ta có thể lấy textContent của tiêu đề, đánh giá, tên người dùng và nội dung, và lấy giá trị thuộc tính data-src trong nút phần tử avatar, đây là địa chỉ URL của avatar.

JavaScript Copy
for (const review of reviewList) {
  const title = await review.$eval(
    'a[data-hook="review-title"] .cr-original-review-content',
    node => node.textContent,
  );
  const rate = await review.$eval(
    'i[data-hook="review-star-rating"] .a-icon-alt',
    node => node.textContent,
  );
  const username = await review.$eval(
    'div[data-hook="genome-widget"] .a-profile-name',
    node => node.textContent,
  );
  const avatar = await review.$eval(
    'div[data-hook="genome-widget"] .a-profile-avatar img',
    node => node.getAttribute('data-src'),
  );
  const content = await review.$eval(
    'span[data-hook="review-body"] span',
    node => node.textContent,
  );
 console.log('[log]===>', { title, rate, username, avatar, content });
}
  • Bước 2. Lưu trữ dữ liệu

Khi chạy đoạn mã trên, bạn sẽ thấy thông tin ghi nhật ký được in ra trong terminal.

kết quả chạy

Nếu bạn muốn lưu trữ dữ liệu này thêm nữa, bạn có thể sử dụng module fs cơ bản của nodejs để ghi dữ liệu vào một file json để phân tích dữ liệu sau này.

Dưới đây là một hàm công cụ đơn giản:

JavaScript Copy
import fs from 'fs';

function saveObjectToJson(obj, filename) {
  const jsonString = JSON.stringify(obj, null, 2)
  fs.writeFile(filename, jsonString, 'utf8', (err) => {
    err ? console.error(err) : console.log(`File saved successfully: ${filename}`);
  });
}

Đoạn mã hoàn chỉnh như sau. Sau khi chạy, bạn có thể tìm thấy amazon_reviews_log.json trong đường dẫn thực thi script hiện tại. Tệp này ghi lại tất cả các kết quả thu thập của bạn!

JavaScript Copy
import puppeteer from 'puppeteer';
import fs from 'fs';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(
  `https://www.amazon.com/Apple-Generation-Cancelling-Transparency-Personalized/product-reviews/B0CHWRXH8B/ref=cm_cr_dp_d_show_all_btm?ie=UTF8&reviewerType=all_reviews`
);

await page.waitForSelector('div[data-hook="review"]');
const reviewList = await page.$$('div[data-hook="review"]');

const reviewLog = []

for (const review of reviewList) {
  const title = await review.$eval(
    'a[data-hook="review-title"] .cr-original-review-content',
    node => node.textContent,
  );
  const rate = await review.$eval(
    'i[data-hook="review-star-rating"] .a-icon-alt',
    node => node.textContent,
  );
  const username = await review.$eval(
    'div[data-hook="genome-widget"] .a-profile-name',
    node => node.textContent,
  );
  const avatar = await review.$eval(
    'div[data-hook="genome-widget"] .a-profile-avatar img',
    node => node.getAttribute('data-src'),
  );
  const content = await review.$eval(
    'span[data-hook="review-body"] span',
    node => node.textContent,
  );
  console.log('[log]===>', { title, rate, username, avatar, content });
  reviewLog.push({ title, rate, username, avatar, content })
}

function saveObjectToJson(obj, filename) {
  const jsonString = JSON.stringify(obj, null, 2)
  fs.writeFile(filename, jsonString, 'utf8', (err) => {
    err ? console.error(err) : console.log(`File saved successfully: ${filename}`);
  });
}

saveObjectToJson(reviewLog, 'amazon_reviews_log.json')
await browser.close()

Các Ví Dụ Chức Năng Khác Của Puppeteer

Hiểu rõ cách sử dụng cơ bản ở trên rồi chứ? Bây giờ, chúng ta có thể tiếp tục khám phá những chức năng mạnh mẽ của Puppeteer. Sau khi chạy các ví dụ sau đây, tôi tin rằng bạn sẽ có cái nhìn mới về công cụ này.

1. Mô phỏng chuyển động chuột

Sử dụng page.mouse.move để điều khiển chuyển động chuột của bạn.

Để bạn cảm nhận rằng con trỏ thực sự di chuyển trên trang, đoạn demo sau là một vòng lặp vô hạn, sẽ khiến chuột di chuyển ngẫu nhiên để kích hoạt kiểu hover của trang.

Lưu ý rằng điều kiện để kích hoạt hover là chuột không di chuyển quá nhanh. Cấu hình tỷ lệ di chuyển steps: 10 trong phương thức move. Và bước này cũng có thể giảm khả năng trang web bị phát hiện.

Page.evaluate là một API rất hữu ích cho phép bạn thực thi mã JavaScript chỉ chạy trong môi trường trình duyệt trong bối cảnh của trang, chẳng hạn như sử dụng window API. Mục đích ở đây là cuộn trang xuống dưới cùng để các bình luận trên trang sẽ được tải đầy đủ.

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto('https://www.google.com');

// Lấy chiều rộng và chiều cao của màn hình
const { width, height } = await page.evaluate(() => {
  return { width: window.innerWidth, height: window.innerHeight };
});

// Vòng lặp vô hạn, mô phỏng chuyển động chuột ngẫu nhiên
while (true) {
  const x = Math.floor(Math.random() * width);
  const y = Math.floor(Math.random() * height);
  await page.mouse.move(x, y, { steps: 10 });
  console.log(`Vị trí chuột: (${x}, ${y})`);
  await new Promise(resolve => setTimeout(resolve, 200)); // Di chuyển mỗi 0.2 giây
}

2. Nhấp vào nút và điền vào biểu mẫu

Chúng ta cũng đã gặp điều này trong demo ban đầu. Thế nào nếu thay đổi cách viết và sử dụng một số API khác để thực hiện nó?

Bạn có thể thấy rằng một số bộ chọn bên dưới được đặt trước bởi >>>, đây là bộ chọn Shadow DOM do Puppeteer cung cấp. Hầu hết các thao tác được thiết lập với một độ trễ thông qua delay, điều này có thể mô phỏng hành vi của người dùng thực tế tốt hơn. Điều này làm cho script của bạn ổn định hơn và tránh kích hoạt cơ chế chống bot của một số trang web.

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: false,
  // defaultView đặt chiều rộng và chiều cao thành 0, có nghĩa là nội dung trang web lấp đầy toàn bộ cửa sổ.
  defaultViewport: { width: 0, height: 0 }
});
const page = await browser.newPage();

await page.goto('https://developer.chrome.com/docs/css-ui?hl=de');

await page.click('>>> button[aria-controls="language-menu"]', { delay: 500 });

// Nhảy đến trang mới và chờ cho đến khi nhảy thành công
await Promise.all([
  page.click('>>> li[role="presentation"]', { delay: 500 }),
  page.waitForNavigation(),
])

// Sử dụng setTimeout làm trình trì hoãn để chờ 2 giây để tải trang
await new Promise(resolve => setTimeout(resolve, 2000))

// Tập trung vào hộp tìm kiếm
await page.focus('input.devsite-search-query', { delay: 500 });

// Nhập văn bản qua bàn phím
await page.keyboard.type('puppeteer', { delay: 200 });

// Kích hoạt phím enter và gửi biểu mẫu
await page.keyboard.press('Enter')

console.log('Biểu mẫu đã gửi thành công');
await page.close()

3. Sử dụng Puppeteer để chụp ảnh màn hình

Puppeteer cung cấp một API chụp ảnh màn hình sẵn có, đây là một tính năng rất thực tế mà chúng ta đã thấy trong các ví dụ trên.

Chất lượng của tệp ảnh màn hình có thể được kiểm soát tốt thông qua chất lượng, và clip được sử dụng để cắt ảnh. Nếu bạn có yêu cầu về tỷ lệ ảnh chụp, bạn cũng có thể thiết lập defaultViewport để đạt được điều đó.

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ defaultViewport: { width: 1920, height: 1080 } });
const page = await browser.newPage();

await page.goto('https://www.youtube.com/');

await page.screenshot({ path: 'screenshot1.png', });
await page.screenshot({ path: 'screenshot2.jpeg', quality: 50 });
await page.screenshot({ path: 'screenshot3.jpeg', clip: { x: 0, y: 0, width: 150, height: 150 } });

console.log('Ảnh chụp màn hình đã được lưu');
await browser.close();

4. Chặn hoặc chặn các yêu cầu trong Puppeteer

Để chặn các yêu cầu, trước tiên bạn cần sử dụng setRequestInterception để kích hoạt việc chặn yêu cầu. Chạy đoạn demo sau và bạn sẽ ngạc nhiên khi thấy kiểu trang bị mất đi, và hình ảnh cũng như biểu tượng biến mất.

Điều này là vì yêu cầu được theo dõi qua trang, và resourceType và url của interceptedRequest được sử dụng để xác định xem có nên hủy bỏ hoặc viết lại yêu cầu tương ứng hay không.

Chúng ta phải lưu ý rằng phương thức isInterceptResolutionHandled nên được gọi trước khi xử lý việc chặn yêu cầu để tránh việc xử lý yêu cầu lặp lại hoặc xung đột.

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

// Kích hoạt việc chặn yêu cầu
await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
  // Tránh yêu cầu bị xử lý lặp lại
  if (interceptedRequest.isInterceptResolutionHandled()) return;
  // Chặn yêu cầu và viết lại phản hồi
  if (interceptedRequest.url().includes('https://fonts.gstatic.com/')) {
    interceptedRequest.respond({
      status: 404,
      contentType: 'image/x-icon',
    })
    console.log('Yêu cầu biểu tượng bị chặn');
    // Chặn yêu cầu kiểu
  } else if (interceptedRequest.resourceType() === 'stylesheet') {
    interceptedRequest.abort();
    console.log('Yêu cầu stylesheet bị chặn');
    // Chặn yêu cầu hình ảnh
  } else if (interceptedRequest.resourceType() === 'image') {
    interceptedRequest.abort();
    console.log('Yêu cầu hình ảnh bị chặn');
  } else {
    interceptedRequest.continue();
  }
});

await page.goto('https://www.youtube.com/');

Tất nhiên, các chức năng trên cũng có thể đạt được với sự trợ giúp của một số công cụ, chẳng hạn như sử dụng Nstbrowser RPA để làm cho crawler của bạn nhanh hơn!

Bước 1. Truy cập trang chính của Nstbrowser, và nhấp vào RPA/Workflow > tạo workflow.

tạo workflow Nstbrowser RPA

Bước 2. Sau khi vào trang chỉnh sửa workflow, bạn có thể tái tạo các chức năng trên bằng cách kéo thả chuột.

Node bên trái có thể đáp ứng gần như tất cả nhu cầu crawler hoặc tự động hóa của bạn, và các node này rất tương thích với API của Puppeteer.

Bạn có thể hiệu chỉnh thứ tự thực thi của các node này bằng cách kết nối chúng như mã JavaScript async. Nếu bạn biết Puppeteer, bạn có thể bắt đầu nhanh chóng với chức năng Nstbrowser RPA. Đó chính là những gì bạn thấy là những gì bạn nhận được.

Các node Nstbrowser RPA

Bước 3. Mỗi Node có thể được cấu hình riêng, và thông tin cấu hình gần như tương ứng với cấu hình của Puppeteer.

a. Chuyển động chuột

chuyển động chuột qua Nstbrowser RPA

b. Nhấp vào nút

Nhấp vào nút qua Nstbrowser RPA

c. Nhậpliệu

Nhập liệu qua Nstbrowser RPA

d. Phím bàn phím

Phím bàn phím

e. Chờ phản hồi

Chờ phản hồi

f. Ảnh chụp màn hình

Ảnh chụp màn hình qua Nstbrowser RPA

Ngoài ra, Nstbrowser RPA có nhiều node phổ biến và độc đáo hơn. Bạn có thể thực hiện các thao tác crawling thông thường bằng cách kéo và thả đơn giản.

Thử ngay miễn phí!

Cài Đặt HTTP Headers Để Tránh Phát Hiện Robot

HTTP headers là thông tin bổ sung được trao đổi giữa client (trình duyệt) và server. Chúng chứa metadata cho các yêu cầu và phản hồi, chẳng hạn như loại nội dung, user agent, cài đặt ngôn ngữ, v.v.

Các headers HTTP phổ biến bao gồm:

  • User-Agent: Xác định loại ứng dụng client, hệ điều hành, phiên bản phần mềm và các thông tin khác.
  • Accept-Language: Chỉ ra ngôn ngữ mà client có thể hiểu và ưu tiên của nó.
  • Referer: Chỉ ra trang nguồn của yêu cầu.

Bằng cách sửa đổi các headers này, bạn có thể ngụy trang như một trình duyệt hoặc hệ điều hành khác, do đó giảm nguy cơ bị phát hiện là robot.

Khi sử dụng Puppeteer, bạn có thể sử dụng phương thức page.setExtraHTTPHeaders để thiết lập các headers trước khi nhảy đến trang web:

JavaScript Copy
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();

// Cài đặt HTTP headers tùy chỉnh
await page.setExtraHTTPHeaders({
  'Accept-Language': 'en-US,en;q=0.9',
  'Referer': 'https://www.google.com',
  'MyHeader': 'hello puppeteer'
});

await page.goto('https://www.httpbin.org/headers');

Nhưng nếu bạn muốn sửa đổi User-Agent, bạn không thể sử dụng phương pháp trên. Vì User-Agent trong trình duyệt có giá trị mặc định. Nếu bạn thực sự muốn thay đổi nó, bạn có thể sử dụng page.setUserAgent.

JavaScript Copy
import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.98 Safari/537.36');

await page.goto('https://example.com/');
const navigator = await page.evaluate(_ => window.navigator.userAgent)
const platform = await page.evaluate(_ => window.navigator.platform)
console.log('userAgent: ', navigator);
console.log('platform: ', platform);
await browser.close();
navigator

Nhưng bước này vẫn chưa đủ. Từ thông tin in ra ở trên, platform vẫn được đặt thành win32 và chưa được thay đổi thực sự.

Hầu hết các trang web phát hiện thông qua window.navigator. Vì vậy, cần phải sửa đổi sâu hơn navigator. Trước khi sử dụng page.goto, chúng ta có thể sửa đổi sâu hơn navigator trong page.evaluateOnNewDocument.

Dưới đây là mô tả ngắn gọn về sự khác biệt giữa page.evaluateOnNewDocument và page.evaluate:

  • Nếu bạn cần sửa đổi môi trường trình duyệt hoặc thực hiện một số thao tác trước mỗi lần tải trang, hãy sử dụng evaluateOnNewDocument.
  • Nếu bạn chỉ cần tương tác với trang hiện tại đã tải hoặc trích xuất dữ liệu. Sử dụng evaluate.
JavaScript Copy
await page.evaluateOnNewDocument(() => {
  Object.defineProperties(navigator, {
    platform: {
      get: () => 'Mac'
    },
  });
});
navigator đã thay đổi

Kết Luận

Mỗi dòng trong bài viết này đóng một vai trò quan trọng để mô tả các hướng dẫn chi tiết nhất về:

  • Headless Chrome là gì?
  • Puppeteer là gì?
  • Làm thế nào để sử dụng headless chrome để thực hiện web scraping?

Muốn thực hiện web scraping và tự động hóa một cách dễ dàng? Nstbrowser RPA giúp bạn đơn giản hóa tất cả các nhiệm vụ.

Hơn
http-2-bypass
Browserless
Phân tích dấu vân tay HTTP/2 và cách vượt qua nó?
Tìm hiểu cách vượt qua dấu vân tay HTTP/2 trong thu thập dữ liệu web với sáu phương pháp mạnh mẽ, từ việc sử dụng trình duyệt thực tế đến Browserless dựa trên đám mây. Tránh bị phát hiện bởi các biện pháp chống bot hiện đại.
Jun 03, 2025Carlos Rivera
Tải tiện ích mở rộng trình duyệt trong Nstbrowser Docker
Browserless
Cách tải tiện ích mở rộng trình duyệt trong Nstbrowser Docker?
Tìm hiểu 2 phương pháp tải tiện ích mở rộng trong Nstbrowser và các bước để khởi chạy chúng trong Docker.
Mar 19, 2025Tạ Quí Lĩnh
Khởi chạy hồ sơ Nstbrowser trong Docker
Browserless
Cách khởi chạy hồ sơ Nstbrowser trong Docker?
Tìm hiểu cách khởi chạy profile Nstbrowser trong Docker, đồng bộ dữ liệu giữa các môi trường và tự động hóa quy trình làm việc bằng API. Hướng dẫn này bao gồm mọi thứ từ thiết lập đến thực thi.
Mar 14, 2025Carlos Rivera
Cách sử dụng Browserless của Nstbrowser để tự động giải quyết Cloudflare Turnstile (2025)
BrowserlessCloudflare BypassHeadless Browser
Cách sử dụng Browserless của Nstbrowser để tự động giải quyết Cloudflare Turnstile (2025)
Tìm hiểu cách bỏ qua Cloudflare Turnstile bằng dịch vụ Browserless của Nstbrowser và Puppeteer. Hướng dẫn này sẽ hướng dẫn bạn thiết lập, triển khai và những lợi thế của việc tự động hóa các tác vụ thu thập dữ liệu web đồng thời đảm bảo sự tuân thủ và hiệu quả.
Mar 07, 2025Triệu Lệ Chi
Cách sử dụng Browserless của Nstbrowser để vượt qua thử thách Cloudflare 5s (2025)
BrowserlessCloudflare BypassHeadless Browser
Cách sử dụng Browserless của Nstbrowser để vượt qua thử thách Cloudflare 5s (2025)
Tìm hiểu cách bỏ qua Thử thách 5s của Cloudflare bằng dịch vụ Browserless của Nstbrowser và Puppeteer. Hướng dẫn này sẽ hướng dẫn bạn thiết lập, triển khai và những lợi thế của việc tự động hóa các tác vụ thu thập dữ liệu web đồng thời đảm bảo sự tuân thủ và hiệu quả.
Mar 06, 2025Robin Brown
Trình duyệt hỗ trợ trí tuệ nhân tạo
Browserless
Browserless: Trình duyệt mạnh mẽ hỗ trợ AI giúp đơn giản hóa tương tác web của bạn
Bài viết này khám phá sự tích hợp mạnh mẽ của các tác nhân AI với Browserless để hợp lý hóa và nâng cao việc thu thập dữ liệu web.
Jan 24, 2025Robin Brown
Mục lục