Puppeteer 谷歌開發是一個 Node 庫,它提供了一個高級 API 來經過 DevTools 協議控制 Chromium 或 Chrome。Puppeteer 默認以 headless 模式運行,可是能夠經過修改配置文件運行「有頭」模式。javascript
能作啥?css
Puppeteer API 是分層次的,反映了瀏覽器結構html
這張圖須要瞭解一下,便是puppeteer的結構,也是代碼的順序結構;java
// 瀏覽器實例
const puppeteer = require('puppeteer');
// 啓動 返回 browser
const browser = await puppeteer.launch();
// 返回 page
const page = await browser.newPage();
// 跳轉
await page.goto('https://www.baidu.com/');
// 返回page的frame
const frame = await page.mainFrame();
// 當前頁面的url https://www.baidu.com/
console.log(frame.url());
// 關閉
await browser.close();
複製代碼
// 安裝puppeteer,若是報錯改用 cnpm 安裝
cnpm install puppeteer --save
複製代碼
Puppeteer返回的大部分是Promise支持一下async/await會很方便; 每一個功能方法都有不少參數配置,先列舉部分git
上方代碼內容
github
await page.goto('https://google.com/', {
// 配置項 等待網絡狀態爲空閒的時候才繼續執行
waitUntil: 'networkidle'
});
複製代碼
await page.screenshot({ path: "download/example.png" });
await page.pdf({
path: "download/example_pdf.pdf',
format: "A4"
});
複製代碼
waitFor: 參數能夠是<string|number|function> 選擇器, 方法 或者 超時時間chrome
// 等待1s
await page.waitFor(1000);
// 等待元素加載完成
await page.waitForSelector("#id");
複製代碼
// 返回單個,若是多個返回第一個,沒有返回null
const ElementHandle = await page.$("#js_login_select")
// 返回多個,若是沒有返回[]
await page.$$(".js_login_select")
複製代碼
此方法在頁面內執行 document.querySelector,而後把匹配到的元素做爲第一個參數傳給 pageFunctionnpm
// 獲取html
const html = await page.$eval("body", e => e.outerHTML);
console.log(html);
// 獲取id
const id = await page.$eval('#div',div => div.id );
//清空輸入框的值,獲取焦點
await page.$eval('#input',input => {
input.focus();
input.value = '';
})
複製代碼
頁面實例上下文中執行的方法json
const dimensions = await page.evaluate(param => {
alert("個人方法dimensions和" + param);
return {
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
deviceScaleFactor: window.devicePixelRatio
};
}, "參數");
複製代碼
page.evaluate 意爲在瀏覽器環境執行腳本,可傳入第二個參數做爲句柄,而 page.$eval 則針對選中的一個 DOM 元素執行操做。api
注意:選擇器過濾後獲得的dom,都是經過執行querySelector或者querySelectorALl獲得的,因此頁面腳本能執行的方法屬性,均可以在這裏使用
Puppetter固然能夠分析網站的性能,不過是建立一個能夠在Chrome DevTools中打開的跟蹤文件。
// 每一個瀏覽器一次只能激活一條跟蹤
await page.tracing.start({
path: "download/trace.json",
screenshots: true
});
// 須要關閉
await page.tracing.stop();
複製代碼
成功後會在path的位置生成.json的文件,裏面一堆的數字和變量~ 打開chrome瀏覽器的devtools,拖進performance中就OK了~
Puppeteer還能夠監聽不少事件,load,error,close等等,固然包括request,response
對頁面的圖片請求攔截,若是不是圖片後綴能夠找規則篩選
// 啓動 request
await page.setRequestInterception(true);
// 監聽request
page.on("request", interceptedRequest => {
if (
interceptedRequest.url().endsWith(".png") || interceptedRequest.url().endsWith(".jpg") ||
interceptedRequest.url().includes(".jpg")
) {
// 中斷
interceptedRequest.abort();
} else {
interceptedRequest.continue();
}
});
await page.goto("https://www.58pic.com/");
複製代碼
await page.addScriptTag({ path: "public/javascripts/test.js" });
await page.addStyleTag({ path: "public/css/test.css" });
複製代碼
這樣不一樣站點,只須要注入不一樣的腳本爬取
關於模擬不一樣的手機,須要不一樣的參數,Puppeteer準備了不少,能夠直接拿來用,在puppeteer/DeviceDescriptors中
const page = await browser.newPage();
// 模擬機型
await page.emulate(iPhone);
複製代碼