基本介紹
Puppeteer 是一個(gè) node 庫,他提供了一組通過 DevTools Protocol
用來操縱 Chrome 和 Chromium 的高層次 API。
Puppeteer 可以用來做幾乎所有可以手動在瀏覽器里面做的事情,目前主要用來做如下工作:
- 利用網(wǎng)頁生成 PDF、圖片
- 爬取SPA應(yīng)用,并生成預(yù)渲染內(nèi)容(即“SSR” 服務(wù)端渲染)
- 自動化表單提交、UI測試、鍵盤輸入等
- 創(chuàng)建一個(gè)最新的自動化測試環(huán)境。可以直接在最新版 Chrome 中測試最新的 JavaScript 和 瀏覽器功能。
- 捕獲站點(diǎn)的時(shí)間線,以便追蹤你的網(wǎng)站,幫助分析網(wǎng)站性能問題
- 測試 Chrome 插件
Puppeteer 是 Chrome 官方團(tuán)隊(duì)進(jìn)行維護(hù)的,因此相較于其他競品例如 PhantomJS 有著更好的穩(wěn)定性和前景。
安裝
Puppeteer 需要 NodeJS 版本不低于6.4.0,但是為了使用 async / await 機(jī)制,NodeJS 版本建議不低于 7.6.0。
npm install puppeteer --save
通過如上命令安裝 Puppeteer 時(shí)同時(shí)會下載最新版 Chromium。
生成 PDF
使用 Puppeteer 生成 PDF 只需要幾行代碼。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.pdf({path: 'example.pdf'});
await browser.close();
})();
大概解讀一下上面幾行代碼:
- 通過 puppeteer.launch() 創(chuàng)建一個(gè)瀏覽器實(shí)例 Browser 對象
- 通過 Browser 對象創(chuàng)建頁面 Page 對象
- 調(diào)用 page.goto() 跳轉(zhuǎn)到指定的頁面
- 調(diào)用 page.pdf() 生成 PDF 文件
- 關(guān)閉瀏覽器
大部分方法都可以通過設(shè)定參數(shù)來來達(dá)到定制化效果
- puppeteer.launch() 方法可以通過設(shè)定 executablePath 來指定運(yùn)行的 Chrome 或 Chromium 路徑。
- page.goto() 方法跟瀏覽器一樣可以指定一個(gè)網(wǎng)頁 url 或者本地文件。
- page.pdf() 可以指定打印格式,自定義頁頭頁尾等。
每個(gè)方法的詳細(xì) API 可以通過官方 API 文檔進(jìn)行查詢。
不難發(fā)現(xiàn),通過 Puppeteer 生成 PDF 的步驟跟手動使用 Chrome 瀏覽器把網(wǎng)頁打印成 PDF 格式的步驟幾乎一樣??梢娖湓O(shè)計(jì)哲學(xué)更符合人類的使用習(xí)慣,更自然。
在 Docker 中使用
在 Docker 中使用 Puppeteer 稍顯復(fù)雜,因?yàn)槠?node 庫中自帶的 Chromium 缺少一些依賴。這些依賴在桌面環(huán)境中一般都已自帶,但是在 Docker 的 node 源鏡像例如 node-alpine 或者 node-slim 是缺失的。所以,在 Docker 中使用 Puppeteer 需要首先安裝這些缺失的依賴。
以 node-aipine 源鏡像為例
FROM node:9-alpine
RUN apk update && apk upgrade && \
echo http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories && \
echo http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories && \
apk add --no-cache \
zlib-dev \
xvfb \
xorg-server \
dbus \
ttf-freefont \
chromium \
nss \
ca-certificates \
dumb-init
這些命令會安裝 Chromium 以及其必要的依賴。安裝 Chromium 是因?yàn)榭梢砸?node-alpine 或者 node-slim 鏡像為基礎(chǔ),安裝好 Chromium 和其他依賴以后打包新的 image 作為項(xiàng)目中使用的 docker 源。這樣可以極大的減少 docker build 的時(shí)間。
加入下面環(huán)境變量可以使得 Puppeteer 跳過下載自帶的 Chromium。
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true
程序使用 Puppeteer 時(shí)需要加入如下參數(shù)
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium-browser',
args: ['--disable-dev-shm-usage', '--no-sandbox']
});
executablePath 參數(shù)指定的是 aipine 版 Chromium 的啟動路徑。
args 參數(shù)中的 --disable-dev-shm-usage 是為了解決 Docker 中 /dev/shm 共享內(nèi)存太小不足以支持 Chromium 運(yùn)行的問題,詳見 TIPS。
args 參數(shù)中的 --no-sandbox 是為了避免 Chromium 在 Linux 內(nèi)核中由 sandbox 導(dǎo)致的啟動問題。