無頭瀏覽器實做筆記
無頭瀏覽器(headless browser),簡單來說,就是沒有 GUI 介面的瀏覽器。如果我們的程式需要瀏覽器的功能:比方說不開瀏覽器截圖(比方說,有網站提供預覽功能?)、載入單頁應用(SPA)……那我們就會考慮無頭瀏覽器。
這裡使用 puppeteer 為範例。
感想……唉,太肥了。光抓一次 puppeteer 就要花去幾分鐘的時間,實在是提不起勁玩無頭瀏覽器啊……
如何截圖?
import { launch } from "puppeteer";
const main = async () => {
// Init
const browser = await launch();
const page = await browser.newPage();
// Settings
await page.setViewport({
width: 1800,
height: 1024,
deviceScaleFactor: 1,
});
await page.goto("https://github.com/");
await page.screenshot({
path: "result.png",
});
await browser.close();
};
main();
如何輸出載入該網頁的資源,比方說 CSS, JavaScript, 圖片等檔案?
如何輸出 SPA 專案會用到的 JSON 檔案?
看了 pixeljets 的範例後才知道訣竅。
於是我就這麼做了:
import { launch } from "puppeteer";
import fs from "fs";
const main = async () => {
const input = "toyota";
// Browser opreation part
const browser = await launch();
const page = await browser.newPage();
// Init page
await page.goto("https://apiroad.net/ajax-test.html");
// Input form
await page.waitForSelector("form > input[type=text]");
await page.type("form > input[type=text]", input);
page.click("#search-button");
// JSON render
const cb = the =>
the.request().url().includes("sample-search.php") &&
the.request().method() != "OPTIONS"
;
const xhrCatcher = page.waitForResponse( cb );
// Get JSON
const xhrResponse = await xhrCatcher;
const xhrPayload = await xhrResponse.json();
console.log( xhrPayload );
await browser.close();
};
main();
先連到網站後,輸入表單並送出資料。而所有回應則使用 waitForResponse 方法,針對連結做對應的過濾判斷,找到與 API 相符的回應後,把回應抓下來。
如何以會員身份抓資料?
幾個想法:
- Cookie
- JWT Token