前端工程師的一大神器——puppeteer

2021-02-28 執鳶者

關注公眾號「執鳶者」,回復「資料」獲取500G資料(各「兵種」均有),還有專業交流群等你一起來瀟灑。(哈哈)

本文主要講述一下Google出版並一直在不斷維護的神器puppeteer,通過學習本文你將了解其基本使用和常用功能。

一、Puppeteer簡介

Puppeteer 是一個 Node 庫,它提供了一個高級 API 來通過 DevTools 協議控制 Chromium 或 Chrome,利用Puppeteer可以獲取頁面DOM節點、網絡請求和響應、程序化操作頁面行為、進行頁面的性能監控和優化、獲取頁面截圖和PDF等,利用該神器就可以操作Chrome瀏覽器玩出各種花樣。

二、Puppeteer核心組成結構

Puppeteer的結構也反映了瀏覽器的結構,其核心結構如下所示:

Browser:這是一個瀏覽器實例,可以擁有瀏覽器上下文,可通過 puppeteer.launch 或 puppeteer.connect 創建一個 Browser 對象。

BrowserContext:該實例定義了一個瀏覽器上下文,可擁有多個頁面,創建瀏覽器實例時默認會創建一個瀏覽器上下文(不能關閉),此外可以利用 browser.createIncognitoBrowserContext()創建一個匿名的瀏覽器上下文(不會與其它瀏覽器上下文共享cookie/cache).

Page:至少包含一個主框架,除了主框架外還有可能存在其它框架,例如iframe。

Frame:頁面中的框架,在每個時間點,頁面通過page.mainFrame()和frame.childFrames()方法暴露當前框架的細節。對於該框架中至少有一個執行上下文

ExecutionCOntext:表示一個JavaScript的執行上下文。

Worker:具有單個執行上下文,便於與 WebWorkers 交互。

三、基本使用和常用功能

該神器整體使用起來比較簡單,下面就開始我們的使用之路。

3.1 啟動Browser

核心函數就是異步調用puppeteer.launch()函數,根據相應的配置參數創建一個Browser實例。

const path = require('path');
const puppeteer = require('puppeteer');

const chromiumPath = path.join(__dirname, '../', 'chromium/chromium/chrome.exe');

async function main() {
// 啟動chrome瀏覽器
const browser = await puppeteer.launch({
// 指定該瀏覽器的路徑
executablePath: chromiumPath,
// 是否為無頭瀏覽器模式,默認為無頭瀏覽器模式
headless: false
});
}

main();

3.2 訪問頁面

訪問頁面首先需要創建一個瀏覽器上下文,然後基於該上下文創建一個新的page,最後指定要訪問的網址。

async function main() {
// 啟動chrome瀏覽器
// ……

// 在一個默認的瀏覽器上下文中被創建一個新頁面
const page1 = await browser.newPage();

// 空白頁訪問該指定網址
await page1.goto('https://51yangsheng.com');

// 創建一個匿名的瀏覽器上下文
const browserContext = await browser.createIncognitoBrowserContext();
// 在該上下文中創建一個新頁面
const page2 = await browserContext.newPage();
page2.goto('https://www.baidu.com');
}

main();

3.3 設備模擬

經常需要不同類型的機型的瀏覽結果,此時就可以採用設備模擬實現,下面模擬一個iPhone X的設備的瀏覽器結果

async function main() {
// 啟動瀏覽器

// 設備模擬:模擬一個iPhone X
// user agent
await page1.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1')
// 視口(viewport)模擬
await page1.setViewport({
width: 375,
height: 812
});

// 訪問某頁面
}

main();

3.4 獲取DOM節點

獲取DOM節點有兩種方式,一種方式是直接調用page所帶的原生函數,另一種是通過執行js代碼獲取。

async function main() {
// 啟動chrome瀏覽器
const browser = await puppeteer.launch({
// 指定該瀏覽器的路徑
executablePath: chromiumPath,
// 是否為無頭瀏覽器模式,默認為無頭瀏覽器模式
headless: false
});

// 在一個默認的瀏覽器上下文中被創建一個新頁面
const page1 = await browser.newPage();

// 空白頁訪問該指定網址
await page1.goto('https://www.baidu.com');

// 等待title節點出現
await page1.waitForSelector('title');

// 用page自帶的方法獲取節點
const titleDomText1 = await page1.$eval('title', el => el.innerText);
console.log(titleDomText1);// 百度一下

// 用js獲取節點
const titleDomText2 = await page1.evaluate(() => {
const titleDom = document.querySelector('title');
return titleDom.innerText;
});
console.log(titleDomText2);
}

main();

3.5 監聽請求和響應

下面就來監聽一下百度中某一js腳本的請求和響應,request事件是監聽請求,response事件是監聽響應。

async function main() {
// 啟動chrome瀏覽器
const browser = await puppeteer.launch({
// 指定該瀏覽器的路徑
executablePath: chromiumPath,
// 是否為無頭瀏覽器模式,默認為無頭瀏覽器模式
headless: false
});

// 在一個默認的瀏覽器上下文中被創建一個新頁面
const page1 = await browser.newPage();

page1.on('request', request => {
if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
console.log(request.resourceType());
console.log(request.method());
console.log(request.headers());
}
});

page1.on('response', response => {
if (response.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
console.log(response.status());
console.log(response.headers());
}
})

// 空白頁剛問該指定網址
await page1.goto('https://www.baidu.com');
}

main();

3.6 攔截某一請求

默認情況下request事件只有隻讀屬性,不能夠攔截請求,若想攔截該請求則需要通過page.setRequestInterception(value)啟動請求攔截器,然後利用request.abort, request.continue 和 request.respond 方法決定該請求的下一步操作。

async function main() {
// 啟動chrome瀏覽器
const browser = await puppeteer.launch({
// 指定該瀏覽器的路徑
executablePath: chromiumPath,
// 是否為無頭瀏覽器模式,默認為無頭瀏覽器模式
headless: false
});

// 在一個默認的瀏覽器上下文中被創建一個新頁面
const page1 = await browser.newPage();

// 攔截請求開啟
await page1.setRequestInterception(true);// true開啟,false關閉
page1.on('request', request => {
if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {
// 終止該請求
request.abort();
console.log('該請求被終止!!!');
}
else {
// 繼續該請求
request.continue();
}
});

// 空白頁訪問該指定網址
await page1.goto('https://www.baidu.com');
}

main();

3.7 截圖

截圖是一個很有用的功能,通過截取就可以保存一份快照,方便後期問題的排查。(註:在無頭模式下進行截圖,否則截的圖可能有問題)

async function main() {
// 啟動瀏覽器,訪問頁面的操作

// 截屏操作,使用Page.screenshot函數
// 截取整個頁面:Page.screenshot函數默認截取整個頁面,加上fullPage參數就是全屏截取
await page1.screenshot({
path: '../imgs/fullScreen.png',
fullPage: true
});

// 截取屏幕中一個區域的內容
await page1.screenshot({
path: '../imgs/partScreen.jpg',
type: 'jpeg',
quality: 80,
clip: {
x: 0,
y: 0,
width: 375,
height: 300
}
});

browser.close();
}

main();

3.8 生成pdf

除了利用截圖保留快照外,還可以使用pdf保留快照。

async function main() {
// 啟動瀏覽器,訪問頁面的操作

// 根據網頁內容生成pdf文件,使用Page.pdf——注意:必須在無頭模式下才可以調用
await page1.pdf({
path: '../pdf/baidu.pdf'
});

browser.close();
}

main();

1.如果覺得這篇文章還不錯,來個分享、點讚、在看三連吧,讓更多的人也看到~

2.關注公眾號執鳶者,領取學習資料,定期為你推送原創深度好文

3.掃描下方添加進群,裡面大佬多多,一起向他們學習


1. 圖解JavaScript——代碼實現(Object.create()、flat()等十四種代碼原理實現不香嗎?)

2. 圖解JavaScript——代碼實現【2】(重點是Promise、Async、發布/訂閱原理實現)

3. 圖解javascript——基礎篇

4. 圖解JavaScript——進階篇

5. 十五張圖帶你徹底搞懂從URL到頁面展示發生的故事

6. 圖解瀏覽器安全(同源策略、XSS、CSRF、跨域、HTTPS、安全沙箱等串成糖葫蘆)

7. 六張圖帶你從HTTP/0.9進化到HTTP3.0

8. (2.6w字)網絡知識點靈魂拷問(上)——前端面試必問

9. (2.6w字)網絡知識點靈魂拷問(下)——前端面試必問

10. 理論與API相結合理解Node中的網絡通信

11. 硬核知識點——瀏覽器中的三類五種請求

12. 理論與實踐相結合徹底理解CORS

13. 三步法解析Express源碼

14. 一篇搞定前端高頻手撕算法題(36道)

15. 十七張圖玩轉Node進程——榨乾它

16. 理論與API相結合理解Node中的網絡通信

17. 一文徹底搞懂前端監控

18. 前端的葵花寶典——架構

相關焦點

  • 前端工程師必備技能匯總
    Git的歷史記錄也可以見證前端行業的一些變遷。儘管會變成文字的方式來維護這些內容,但是我承諾寫一個小工具幫大家生成更好玩的圖形(基於DataV項目)。前端開發知識結構●前端工程師●SVG/Canvas/VML●SVG: D3/Raphaël/Snap.svg/DataV●Canvas: CreateJS/KineticJS●知識管理/總結分享●溝通技巧/團隊協作●需求管理/PM●互動設計/
  • Puppeteer在客服業務線中的落地實踐
    1,如何模擬多端以及不同的APP來打開同一M頁模擬不同的行動裝置,首先Puppeteer提供了模擬行動裝置的庫,位置在工程的:/node_modules/puppeteer/DeviceDescriptors,我們可以直接引用,如模擬一個iPhone 6設備,下圖為DeviceDescriptors文件配置:使用方式:
  • 前端切圖神器Avocode
    作者:john mike(極樂科技知乎專欄原創作者)出處:https://zhuanlan.zhihu.com/p/25176758版權歸作者所有,轉載請註明出處安裝avocode前端的基礎工作就是把設計師的設計稿還原成前端頁面
  • 前端切圖神器avocode
    01安裝avocode前端的基礎工作就是把設計師的設計稿還原成前端頁面,所以切圖是作為一個前端的基本技能。
  • ICspec|電子工程師的神器......竟然是它?
    它就是電子工程師的神器——555定時器,從誕生到現在,銷量過百億,電路設計從沒有大改變,可以說是歷史上最成功最經典的晶片。在四十多年的時間裡,全球的電子工程師們,前赴後繼,用555實現了一個又一個應用電路,其應用非常廣泛。究竟有多廣泛?下面,就為大家展示下555定時器都能做什麼。555放大器電路555可被用做放大器,工作模式非常類似於PWM。
  • 常用的幾款前端開發編輯器對比
    |  譯者: 京東金融-移動研發部-前端開發工程師 沈霍伊
  • 軟體工程師的鄙視鏈
    不是把重複的 code 寫成一個 function 就好了嗎?」的工程師鄙視把同一段 code 到處複製貼上的工程師,把同一段 code 到處複製貼上的工程師鄙視 PM。寫靜態語言的工程師鄙視寫動態語言的工程師。
  • 我從國企辭職了,決定去做全棧工程師
    我是一個全棧工程師!那什麼是全棧工程師?全棧工程師,也叫全端工程師,英文Full Stack developer,是指掌握多種技能,並能利用多種技能獨立完成產品的人。全棧工程師是指,一個能處理資料庫、伺服器、系統工程和客戶端的所有工作的工程師。根據項目的不同,客戶需要的可能是移動棧、Web棧,或者原生應用程式棧。
  • 可視化:前端人的未來
    作為前端領域中一個幾乎不用寫網頁的特殊分支,可視化利用計算機的圖形學和圖像處理技術,將數據轉換成圖形或圖像,在屏幕上顯示出來,並進行交互處理。將 GitHub 中提交開源項目的次數做成 3D 可視化圖表 所以,行業對可視化工程師的需求越來越大,很多一線網際網路公司都設有相關崗位
  • 《八方匯PLC調試神器》的使用說明--Modbus通訊篇
    在電腦上打開《八方匯PLC調試神器》,選擇「通訊調試」:我們使用調試神器來代替PLC來對溫控器發送報文命令,調試神器選擇主站,作為發送數據的一方。,則說明PLC到調試神器的通訊正常。課程內容包括工程師負責的一整套流程,還包括學員學出去走上工程師崗位以後提供的技術支持,特殊情況導師可親自上門服務服務贈送課程:電磁閥應用課程、電氣CAD繪圖課程、控制箱接線智慧、電工補習課程、電腦快速應用課程、電氣工程師面試課程、電氣工程師職業智慧、
  • 5G射頻前端模組的前世與今生
    最近十幾年中,射頻前端方案快速演進。「模組化」是射頻前端演進的重要方向。 射頻前端的「模組化」究竟是什麼, 它是怎麼來的,又有什麼挑戰? 帶著以上問題,本文對射頻前端模組的發展過程做一個梳理,對射頻前端產品模組化進程中的挑戰和未來可能的演進做一個討論。射頻前端是指天線後,收發機之前的部分。
  • 射頻前端模組
    該模塊集成了整個射頻前端所需要的發射頻段。包括帶偏差控制器的寬帶PA、Tx諧波濾波器、天線開關和MIPI控制器。Smarter Micro慧智微WiFi射頻前端 S3217高度集成5GHz前端模塊(FEM),包含5GHz的單杆、雙擲(SPDT)傳輸/接收(t/r)開關,和帶支路的5 GHz低噪音放大器(LNA),
  • 前端離線化探索
    比如,用戶點擊按鈕,前端更新數據狀態為成功,請求到達後臺,伺服器響應,更新前端數據。我們看下常見的離線數據前端方案。PouchDBPouchDB 是一個跨平臺javascript 資料庫,內部封裝了IndexDB、WebSql兼容前端處理.一般而言前端pouchDB進行離線處理,搭配後臺CouchDB,可以更方便雙向數據同步。Sync 接口專門用不同步前後的數據:
  • 器皿中的神靈,神器盤點!
    神器,宇宙中最強大的兵器,歷史上甚至出現過神器諸天,戰力強悍到沒有修士配執掌它。哪怕不說那種特殊的例子,神器在器皿世界裡也是神靈一樣的存在。現在神器對我們來說已經不陌生,今天就來盤點一波這些器皿中的神靈!
  • 緬懷將消失的系統 DNF你曾追逐的領主神器
    刪除的系統中就包含領主神器系統,上一期我們已經聊過了一批讓DNF玩家無比追求的領主神器今天我們接著這個話題繼續聊。那個時候還是神器當道,很多買不起神器裝備的玩家就選擇硬剛這把武器。屬性方面是比較強力的,15%的機率附加10%的火屬性傷害,高火強的話擁有不俗的戰鬥力。
  • 寫給前端新手看的一些模塊化知識
    大廠技術  高級前端
  • 前端模塊化的今生
    作者:Shenfq — 拼多多前端工程師 背景眾所周知,早期 JavaScript 原生並不支持模塊化,直到 2015 年,TC39
  • 「寫字機器人」成補作業「神器」?
    市民彭先生供圖      暑假開始,一條「寫字神器」刷作業直接衝上了微博熱搜,引來數萬網友圍觀調侃。「寫字神器」真能補作業嗎?記者多天的調查發現,這款「神器」從安裝到熟練應用,沒有家長的協助,小學生是很難完成的。
  • Jupyter Notebook的終極神器 | Tool
    因為沒有看新的項目, 今天就再介紹一個提高coding效率的神器. 集合幾十種殺人武器於一身的超級武器霸王, 名字就叫做要你命3000!走錯片場了! 不好意思! 是nbextensions!Nbextensions是Jupyter Notebook的一個終極神器, 是一個各類擴展功能的集合包.我一直以為它是中國人的開發的, 因為叫做NB-extensions…嗯..niubi..灰常niubi的extensions…沒錯! 小時候到我也一度以為NB鞋也是國產的!言歸正傳, 下面介紹幾個我比較常用的小功能.1.