Puppeteer
Google Chrome 官方團隊推出的 Node.js Library
讓使用者可透過 DevTools Protocol 控制無介面的 Chrome 基礎使用
code:javascript
// 引入 puppeteer
const puppeteer = require('puppeteer')
const url = ''
(async() => {
// 啟動 puppeteer
const browser = await.puppeteer.launch({
// 使用背景模式執行
headless: true,
});
// 開啟新分頁
const page = await browser.newPage();
// 前往頁面
await page.goto(url);
// action here...
// 關閉 puppeteer
await browser.close()
})
// 也可使用 then 撰寫
puppeteer.launch({ headless: false }).then(async browser => {
const page = await browser.newPage();
await page.goto(url);
// action here...
await browser.close();
})
.launch()
headless: [boolean]:是否以背景模式執行瀏覽器
useDataDir: [string]:儲存使用者的相關資料
slowMo: [number]:設定每個操作的延遲毫秒數
args: [array[string]]:設定傳入給瀏覽器的相關參數
timeout: [number]:等待瀏覽器啟動的時間長度
devtools: [boolean]:啟動後是否開啟開發者工具列
啟用此選項時 headless 必須為 true
取得 DOM
code:javascript
// 取得 DOM
await page.$(".listItem ul li");
// 取得 DOM 裡的值
const target = await page.$(".listItem ul li");
const targetText = await page.evaluate(
(_target) => _target.textContent,
target
);
// 等同於
const targetText = await page.$eval(".listItem ul li", (el) => el.textContent);
// 也可以取得 DOM 的其它屬性,例如 HTML 內容,或是連結網址
const targetText = await page.$eval(".listItem ul li", (el) => el.innerHTML);
const href = await page.$eval(".btn-download", (el) => el.getAttribute("href"));
// 取得所有節點
const targets = await page.$$("a");
// 同樣可以結合 evaluate 使用,但傳入的是 DOM 陣列,需要再做一次迭代處理
const targets = await page.$$eval("a", (els) => els.map((el) => el.innerHTML));
操作 DOM
code:javascript
// 輸入內容
await page.type("#email", "example@example.com");
// 點擊元素
await page.click("#loginButton");
const agreeButton = await page.$(".btn-input");
await agreeButton.click({ clickCount: 1, delay: 100 });
// 截圖頁面
await page.screenshot({ path: "screenshot.png" });
// 截圖指定元素
const element = await page.$("h1");
await element.screenshot({ path: "screenshot_h1.png" });
等待頁面
code:javascript
// 點擊同意按鈕
const agreeButton = await page.$(".btn-input");
await agreeButton.click({ clickCount: 1, delay: 100 });
// 點擊後網頁會自動跳頁,因此等待至跳轉完畢,再進行後續處理
await page.waitForNavigation({ waitUntil: "networkidle0" });
// some other execution...
page.waitFor(selector/function/timeout[, options[, args]])
等待 selector 出現/function 執行完畢/時間過後,才執行後面動作
page.waitForNavigation(options)
等待頁面跳轉完,才執行後面動作
通常用於點擊連結或同意使用者規約等等,頁面會發生跳轉的行為
page.waitForSelector(selector[, options])
等待至元素出現,才執行後面動作
page.waitForRequest(url/predicate, options)
等待 request 處理完畢
page.waitForResponse(url/predicate, options)
等待獲得 response
使用 cookie
code:javascript
const fs = require("fs");
// 從本地端讀取 oookie 檔案
const cookies = JSON.parse(fs.readFileSync("./cookies.json", "utf-8"));
await page.setCookie(...cookies);
儲存檔案
puppeteer 只有提供截圖功能,沒有下載檔案的 function
想要下載檔案的話,需要再搭配 fs,以及 $eval
code:javascript
const fs = require("fs");
// 取得檔案連結
const href = await page.$eval(".btn-download", (anchor) =>
anchor.getAttribute("href")
);
// 取得檔案名稱
const split = href.split("/");
// 取得檔案資料
let bufferData = await page.goto(href);
// 使用 fs 下載檔案
fs.writeFileSync(
"./download/" + filename,
await bufferData.buffer(),
function (err) {
if (err) {
throw err;
}
console.log("File saved!");
}
);
相關連結