Về Field Notes

Kết hợp n8n và Puppeteer:
Tự động hoá web động không cần code

n8n và Puppeteer là gì?

n8n
Nền tảng workflow automation self-hosted. Giao diện kéo thả kết nối 400+ service — không cần viết code cho các tác vụ tích hợp thông thường.
Puppeteer
Thư viện Node.js của Google, điều khiển Chrome/Chromium qua DevTools Protocol. Chạy headless — không cần màn hình, tự động mọi thao tác trình duyệt.

Nếu n8n là "bộ não" điều phối luồng công việc, thì Puppeteer là "đôi tay" có thể thao tác trực tiếp lên bất kỳ trang web nào — giống hệt người dùng thật ngồi trước màn hình.

Tại sao cần kết hợp cả hai?

Node HTTP Request mặc định của n8n gửi request thẳng đến server và nhận HTML về — đủ dùng cho phần lớn API và trang web tĩnh. Nhưng web hiện đại không đơn giản như vậy.

Single Page Applications (React, Vue, Angular) render nội dung bằng JavaScript sau khi tải trang. HTTP Request chỉ lấy được HTML khung rỗng — nội dung thực sự chưa được render. Puppeteer mở trình duyệt thật, chờ JavaScript chạy xong, rồi mới đọc DOM.

  • Vượt qua trang web động: SPA, lazy-load, infinite scroll, nội dung render bằng JS
  • Tương tác phức tạp: Click, điền form, kéo thả, hover, đăng nhập multi-step
  • Chụp ảnh & PDF: Screenshot full-page hoặc element cụ thể, xuất PDF
  • Bypass anti-bot cơ bản: Giả lập User-Agent, viewport, mouse movement
  • Quản lý trực quan: Toàn bộ logic trong n8n workflow — không cần deploy script riêng

HTTP Request vs Puppeteer: chọn cái nào?

Tình huống HTTP Request Puppeteer
Trang web tĩnh, HTML đầy đủ ngay khi tải ✓ Dùng được Overkill
REST API trả về JSON ✓ Tốt nhất Không cần
Single Page App (React, Vue, Angular) ✗ Không đủ ✓ Cần dùng
Cần đăng nhập, điền form nhiều bước ✗ Phức tạp ✓ Phù hợp
Infinite scroll, lazy-load content ✗ Không bắt được ✓ Scroll được
Chụp ảnh màn hình, xuất PDF ✗ Không hỗ trợ ✓ Built-in
Tốc độ thực thi, tài nguyên thấp ✓ Nhanh, nhẹ Nặng hơn ~200MB RAM/tab
Nguyên tắc thực hành: Luôn thử HTTP Request trước. Chỉ chuyển sang Puppeteer khi HTTP Request không lấy được nội dung cần — Puppeteer tốn tài nguyên hơn đáng kể (mỗi tab Chrome ~150–300 MB RAM).

Cài đặt Community Node Puppeteer

Puppeteer không có sẵn trong n8n mặc định — cần cài qua Community Nodes. Quy trình:

  1. Vào Settings (góc trái dưới) → Community Nodes
  2. Click Install a community node
  3. Điền package name: n8n-nodes-puppeteer
  4. Tick xác nhận rủi ro → Install
  5. Chờ cài xong, node mới xuất hiện khi search "Puppeteer" trong workflow editor
Community Nodes yêu cầu biến môi trường N8N_COMMUNITY_PACKAGES_ENABLED=true trong cấu hình n8n. Nếu không thấy menu Community Nodes, kiểm tra biến này trước.

Workflow đầu tiên: chụp ảnh trang web

Bắt đầu với ví dụ đơn giản nhất — chụp ảnh full-page một URL. Từ đây bạn hiểu được cấu trúc node Puppeteer trước khi làm các tác vụ phức tạp hơn.

1
Tạo trigger Manual Kéo node "Manual Trigger" vào canvas — dùng để chạy thủ công khi test
2
Thêm node Puppeteer Search "Puppeteer" trong node panel, kéo vào và nối với Manual Trigger
Operation: Get Screenshot
URL: https://www.google.com
Type: PNG
Full Page: true
3
Chạy và kiểm tra output Click "Execute workflow" → chọn node Puppeteer → tab Binary trong Output sẽ có ảnh PNG
4
Lưu ảnh hoặc gửi đi Nối tiếp node Write Binary File (lưu vào disk), Send Email (đính kèm), hoặc HTTP Request (upload lên API)

Khắc phục lỗi trên Docker / Alpine Linux

Khi chạy n8n trong Docker (đặc biệt image dùng Alpine Linux), Puppeteer thường báo lỗi vì Chrome không tìm thấy các thư viện hệ thống cần thiết.

Lỗi thường gặp
Could not find Chrome
Puppeteer không tìm thấy binary Chrome.

Missing libraries
libX11, libglib, nss, freetype... không tồn tại trong Alpine tối giản.

Sandbox error
Running as root without --no-sandbox is not supported.
Giải pháp
Cài Chromium vào container:
Thực thi trong container đang chạy.

Cấu hình đường dẫn & flags:
Trỏ Puppeteer đến Chromium vừa cài, tắt sandbox.

Hoặc: dùng biến môi trường
Khai báo trong docker-compose.yml để áp dụng vĩnh viễn.

Bước 1 — Cài Chromium vào container Alpine:

shell — trong container đang chạy
# Exec vào container với quyền root docker exec -it -u root <tên_container> sh # Cài Chromium và các thư viện phụ thuộc apk add --no-cache \ chromium \ nss \ freetype \ harfbuzz \ ca-certificates \ ttf-freefont

Bước 2 — Cấu hình node Puppeteer trong n8n:

Executable Path: /usr/bin/chromium-browser
Launch Arguments: --no-sandbox --disable-setuid-sandbox --disable-dev-shm-usage
Headless: true

Bước 3 — Hoặc khai báo trong docker-compose.yml để tránh cấu hình lại mỗi lần:

docker-compose.yml
services: n8n: image: n8nio/n8n:latest environment: # Trỏ Puppeteer đến Chromium đã cài trong Alpine - PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true # Bật Community Nodes - N8N_COMMUNITY_PACKAGES_ENABLED=true volumes: - n8n_data:/home/node/.n8n
--disable-dev-shm-usage quan trọng trong Docker vì /dev/shm mặc định chỉ có 64 MB — Chrome sẽ crash khi render trang phức tạp. Flag này chuyển sang dùng /tmp thay thế.

Các tác vụ nâng cao

📝
Tự động điền form
Dùng action Type + Click để điền và submit form — hữu ích cho upload dữ liệu vào hệ thống không có API.
✓ Dùng khi: form nhiều bước, captcha-free
📊
Thu thập dữ liệu SPA
Chờ selector xuất hiện, đọc text/attribute — lấy dữ liệu từ React/Vue app mà HTTP Request không lấy được.
✓ Dùng khi: trang render bằng JS
📸
Screenshot & PDF báo cáo
Chụp dashboard, chart, hoặc xuất invoice/báo cáo sang PDF tự động — gửi qua email định kỳ.
✓ Dùng khi: cần visual output
🔐
Đăng nhập & session
Login, lưu cookie session, thực hiện tác vụ sau đăng nhập — tự động hoá portal nội bộ không có API key.
✓ Dùng khi: cần authenticated scraping
REST API công khai
Trang có sẵn API endpoint trả JSON — dùng HTTP Request nhanh hơn, ít tài nguyên hơn nhiều.
✗ Không cần Puppeteer
📄
Trang HTML tĩnh
Nội dung đã có trong HTML response ban đầu, không cần JS render — HTTP Request + HTML Extract đủ dùng.
✗ Overkill khi dùng Puppeteer

Trích xuất dữ liệu bằng CSS Selector

Trong node Puppeteer, operation Get Content cho phép lấy text từ element bất kỳ — dùng CSS Selector giống DevTools:

Puppeteer — Get Content config
Operation : Get Content URL : https://example.com/products Selector : .product-card .price ← CSS selector từ DevTools Wait For : networkidle0 ← chờ trang load xong hoàn toàn Attribute : innerText ← hoặc innerHTML, href, src...

Tips vận hành thực tế

  • Dùng waitForSelector thay vì networkidle: Chờ đúng element xuất hiện nhanh hơn chờ toàn bộ network idle — tránh timeout không cần thiết.
  • Giới hạn đồng thời: Mỗi tab Puppeteer tốn ~200 MB RAM. Nếu workflow chạy song song, set concurrency tối đa trong n8n Settings → Executions để tránh OOM.
  • User-Agent thực tế: Một số site block request từ Headless Chrome. Set User-Agent thành Chrome bình thường trong Launch Arguments: --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120..."
  • Timeout hợp lý: Default timeout của Puppeteer là 30 giây. Với trang nặng, set Page Timeout lên 60–90 giây trong node config.
  • Không dùng Puppeteer cho scraping quy mô lớn: Nếu cần crawl hàng nghìn URL, dùng HTTP Request + queue. Puppeteer phù hợp cho tác vụ lẻ hoặc batch nhỏ có tương tác.
n8n + Puppeteer giải quyết được lớp bài toán mà trước đây cần cả một script Python và cronjob riêng. Kéo thả, cấu hình, chạy — không cần deploy, không cần maintain server script riêng biệt.