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.
Mục Lục
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
-
Tạo một thư mục dự án mới:
mkdir puppeteer-example cd puppeteer-example -
Khởi tạo dự án Node.js:
npm init -y -
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ế
''trongcookie.valuebằng giá trị cookieviblo_auththự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:
