Puppeteer: Thư Viện Node.js Kiểm Soát Trình Duyệt Chrome/Chromium Headless và Ứng Dụng Thực Tế

Puppeteer là một thư viện Node.js cung cấp API cấp cao để điều khiển các trình duyệt Chrome hoặc Chromium ở chế độ headless (không giao diện). Nó cũng có thể được cấu hình để sử dụng các phiên bản Chrome hoặc Chromium đầy đủ (có giao diện). Điều này mở ra vô vàn khả năng tự động hóa các tác vụ liên quan đến trình duyệt, từ việc thu thập dữ liệu đến kiểm thử giao diện người dùng.

1. Puppeteer là gì và tại sao nó lại hữu ích?

Hiểu một cách đơn giản, Puppeteer cho phép bạn “lập trình” trình duyệt. Thay vì thao tác thủ công trên trình duyệt, bạn có thể viết mã để tự động thực hiện các hành động như:

  • Chụp ảnh màn hình và tạo PDF: Lưu lại trang web hiện tại dưới dạng hình ảnh hoặc tài liệu PDF.
  • Crawl dữ liệu: Thu thập thông tin từ các trang web, đặc biệt hữu ích với các SPA (Single-Page Application) và tạo ra nội dung pre-rendered để cải thiện SEO.
  • Tự động hóa thao tác: Điền và gửi biểu mẫu, tương tác với các thành phần giao diện người dùng, và mô phỏng hành vi người dùng như nhập liệu từ bàn phím.
  • Kiểm thử tự động: Xây dựng các bài kiểm thử tự động cho giao diện người dùng, đảm bảo ứng dụng hoạt động đúng như mong đợi trên các phiên bản Chrome/Chromium mới nhất.
  • Ghi lại timeline trace: Phân tích hiệu năng website và xác định các điểm nghẽn.
  • Kiểm thử Chrome Extensions: Đảm bảo các tiện ích mở rộng hoạt động chính xác.

Trong bài viết này, chúng ta sẽ tập trung vào việc sử dụng Puppeteer để chụp ảnh màn hình và xuất file PDF.

2. Các hàm (API) quan trọng trong Puppeteer

Để sử dụng Puppeteer hiệu quả, bạn cần nắm vững một số hàm cơ bản sau:

2.1 browser.launch([options])

Hàm launch([options]) khởi chạy một phiên bản trình duyệt mới. options là một đối tượng chứa các tùy chọn cấu hình.

Các tùy chọn phổ biến:

Option Mô tả Kiểu dữ liệu Mặc định
product Chọn trình duyệt, có thể là chrome hoặc firefox. String
ignoreHTTPSErrors Bỏ qua lỗi HTTPS trong quá trình điều hướng. Boolean false
headless Chạy trình duyệt ở chế độ headless (không giao diện). Boolean true
executablePath Đường dẫn đến file thực thi của trình duyệt. String
slowMo Làm chậm các thao tác của Puppeteer theo milliseconds (giúp dễ quan sát quá trình). Number
defaultViewport Đặt kích thước viewport (khu vực hiển thị) của trang web. Object
args Các đối số dòng lệnh bổ sung để truyền cho trình duyệt. Array
timeout Thời gian tối đa (milliseconds) để khởi động trình duyệt. Đặt 0 để tắt timeout. Number 30000

Ví dụ:

const browser = await puppeteer.launch({ headless: false, slowMo: 250 }); // Khởi chạy Chrome có giao diện, làm chậm các thao tác 250ms

Tham khảo chi tiết tại đây.

2.2 page.goto(url[, options])

Hàm goto(url[, options]) điều hướng trình duyệt đến một URL cụ thể.

Các tham số:

  • url: URL cần điều hướng đến.
  • options: Các tùy chọn điều hướng.

Các tùy chọn phổ biến:

Option Mô tả Kiểu dữ liệu Mặc định
timeout Thời gian tối đa (milliseconds) để điều hướng. Number 30000
waitUntil Xác định khi nào điều hướng được coi là thành công. Các giá trị có thể là: load, domcontentloaded, networkidle0, networkidle2. String load
referer Cung cấp HTTP referer header. String

Ví dụ:

await page.goto('https://www.google.com', { waitUntil: 'networkidle2' }); // Điều hướng đến Google, chờ cho đến khi mạng ở trạng thái nhàn rỗi

Tham khảo chi tiết tại đây.

2.3 page.pdf([options])

Hàm pdf([options]) tạo ra một file PDF từ trang HTML hiện tại.

Các tùy chọn:

Option Mô tả Kiểu dữ liệu Mặc định
path Đường dẫn để lưu file PDF. Nếu không có, file sẽ không được lưu. String
scale Tỉ lệ của trang web. Nhận giá trị từ 0.1 đến 2. Number 1
displayHeaderFooter Hiển thị header và footer. Boolean false
headerTemplate HTML template cho header. Có thể sử dụng các biến như date, title, url, pageNumber, totalPage. String
footerTemplate HTML template cho footer. Tương tự như headerTemplate. String
printBackground In background. Boolean false
landscape Hướng giấy (ngang hoặc dọc). Boolean false
pageRanges Phạm vi trang để in (ví dụ: 1-5, 8, 11-13). String
format Định dạng giấy (ví dụ: Letter, A4). String Letter
width Chiều rộng. String | Number
height Chiều cao. String | Number
margin Căn lề. Object
preferCSSPageSize Ưu tiên định dạng CSS so với các khai báo tùy chọn. Boolean false

Ví dụ:

await page.pdf({ path: 'example.pdf', format: 'A4', printBackground: true }); // Xuất file PDF định dạng A4, in background

Tham khảo chi tiết tại đây.

3. Thực hành với Puppeteer

Bây giờ, chúng ta sẽ cùng nhau thực hiện một vài ví dụ đơn giản để làm quen với Puppeteer.

3.1. Chuẩn bị môi trường

  1. Tạo một thư mục dự án mới:

    mkdir puppeteer-example
    cd puppeteer-example
  2. Khởi tạo dự án Node.js:

    npm init -y
  3. Cài đặt Puppeteer:

    npm install puppeteer --save

3.2 Chụp ảnh màn hình

Tạo một file screenshot.js với nội dung sau:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://viblo.asia');
  await page.screenshot({ path: 'viblo.png' });
  await browser.close();
})();

Chạy file:

node screenshot.js

Kết quả: Một file ảnh viblo.png sẽ được tạo ra trong thư mục dự án, chứa ảnh chụp màn hình trang Viblo.asia.

3.3 Xuất file PDF

Tạo một file pdf.js với nội dung sau:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://viblo.asia', { waitUntil: 'networkidle2' });
  await page.pdf({ path: 'viblo.pdf', format: 'A4', printBackground: true });
  await browser.close();
})();

Chạy file:

node pdf.js

Kết quả: Một file PDF viblo.pdf sẽ được tạo ra, chứa nội dung trang Viblo.asia.

3.4 Chụp ảnh trang yêu cầu xác thực (Authentication)

Nếu bạn muốn chụp ảnh một trang yêu cầu đăng nhập, bạn cần thiết lập cookie trước khi truy cập trang đó. Ví dụ, để chụp trang viết bài của Viblo, bạn cần có cookie xác thực.

const puppeteer = require('puppeteer');

(async () => {
  const cookie = {
    name: 'viblo_auth',
    value: '', // **CẦN THAY THẾ BẰNG GIÁ TRỊ COOKIE THỰC TẾ**
    domain: 'viblo.asia',
    url: 'https://viblo.asia',
    path: '/',
    httpOnly: true,
    secure: true,
  };
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setCookie(cookie);
  await page.goto('https://viblo.asia/publish/post', { waitUntil: 'networkidle2' });
  await page.screenshot({ path: 'viblo-authenticated.png' });
  await browser.close();
})();

Lưu ý quan trọng:

  • Bạn cần thay thế '' trong cookie.value bằng giá trị cookie viblo_auth thực tế của bạn. Bạn có thể tìm thấy cookie này trong trình duyệt sau khi đăng nhập vào Viblo.
  • Việc lấy cookie và sử dụng nó có thể vi phạm điều khoản dịch vụ của một số trang web. Hãy sử dụng một cách có trách nhiệm.

4. Kết luận

Puppeteer là một công cụ mạnh mẽ để tự động hóa và kiểm soát trình duyệt Chrome/Chromium. Với khả năng chụp ảnh màn hình, tạo PDF, thu thập dữ liệu, và kiểm thử giao diện người dùng, Puppeteer mở ra nhiều cơ hội để cải thiện quy trình làm việc và nâng cao chất lượng ứng dụng web của bạn. Hãy tiếp tục khám phá và thử nghiệm với Puppeteer để tận dụng tối đa sức mạnh của nó.

Tài liệu tham khảo: