自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 開發(fā)工具
Puppeteer 是一個(gè) Node 庫,它提供了一個(gè)高級(jí) API 來通過 DevTools 協(xié)議控制 Chromium 或 Chrome,利用Puppeteer可以獲取頁面DOM節(jié)點(diǎn)、網(wǎng)絡(luò)請(qǐng)求和響應(yīng)、程序化操作頁面行為、進(jìn)行頁面的性能監(jiān)控和優(yōu)化、獲取頁面截圖和PDF等,利用該神器就可以操作Chrome瀏覽器玩出各種花樣。

 [[379603]]

本文主要講述一下Google出版并一直在不斷維護(hù)的神器puppeteer,通過學(xué)習(xí)本文你將了解其基本使用和常用功能。

 

一、Puppeteer簡(jiǎn)介

Puppeteer 是一個(gè) Node 庫,它提供了一個(gè)高級(jí) API 來通過 DevTools 協(xié)議控制 Chromium 或 Chrome,利用Puppeteer可以獲取頁面DOM節(jié)點(diǎn)、網(wǎng)絡(luò)請(qǐng)求和響應(yīng)、程序化操作頁面行為、進(jìn)行頁面的性能監(jiān)控和優(yōu)化、獲取頁面截圖和PDF等,利用該神器就可以操作Chrome瀏覽器玩出各種花樣。

二、Puppeteer核心組成結(jié)構(gòu)

Puppeteer的結(jié)構(gòu)也反映了瀏覽器的結(jié)構(gòu),其核心結(jié)構(gòu)如下所示:

 

  1. Browser:這是一個(gè)瀏覽器實(shí)例,可以擁有瀏覽器上下文,可通過 puppeteer.launch 或 puppeteer.connect 創(chuàng)建一個(gè) Browser 對(duì)象。
  2. BrowserContext:該實(shí)例定義了一個(gè)瀏覽器上下文,可擁有多個(gè)頁面,創(chuàng)建瀏覽器實(shí)例時(shí)默認(rèn)會(huì)創(chuàng)建一個(gè)瀏覽器上下文(不能關(guān)閉),此外可以利用 browser.createIncognitoBrowserContext()創(chuàng)建一個(gè)匿名的瀏覽器上下文(不會(huì)與其它瀏覽器上下文共享cookie/cache).
  3. Page:至少包含一個(gè)主框架,除了主框架外還有可能存在其它框架,例如iframe。
  4. Frame:頁面中的框架,在每個(gè)時(shí)間點(diǎn),頁面通過page.mainFrame()和frame.childFrames()方法暴露當(dāng)前框架的細(xì)節(jié)。對(duì)于該框架中至少有一個(gè)執(zhí)行上下文
  5. ExecutionCOntext:表示一個(gè)JavaScript的執(zhí)行上下文。
  6. Worker:具有單個(gè)執(zhí)行上下文,便于與 WebWorkers 交互。

三、基本使用和常用功能

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

3.1 啟動(dòng)Browser

核心函數(shù)就是異步調(diào)用puppeteer.launch()函數(shù),根據(jù)相應(yīng)的配置參數(shù)創(chuàng)建一個(gè)Browser實(shí)例。

  1. const path = require('path'); 
  2. const puppeteer = require('puppeteer'); 
  3.  
  4. const chromiumPath = path.join(__dirname, '../''chromium/chromium/chrome.exe'); 
  5.  
  6. async function main() { 
  7.     // 啟動(dòng)chrome瀏覽器 
  8.     const browser = await puppeteer.launch({ 
  9.         // 指定該瀏覽器的路徑 
  10.         executablePath: chromiumPath, 
  11.         // 是否為無頭瀏覽器模式,默認(rèn)為無頭瀏覽器模式 
  12.         headless: false 
  13.     }); 
  14.  
  15. main(); 

3.2 訪問頁面

訪問頁面首先需要?jiǎng)?chuàng)建一個(gè)瀏覽器上下文,然后基于該上下文創(chuàng)建一個(gè)新的page,最后指定要訪問的網(wǎng)址。

  1. async function main() { 
  2.     // 啟動(dòng)chrome瀏覽器 
  3.     // …… 
  4.  
  5.     // 在一個(gè)默認(rèn)的瀏覽器上下文中被創(chuàng)建一個(gè)新頁面 
  6.     const page1 = await browser.newPage(); 
  7.  
  8.     // 空白頁訪問該指定網(wǎng)址 
  9.     await page1.goto('https://51yangsheng.com'); 
  10.  
  11.     // 創(chuàng)建一個(gè)匿名的瀏覽器上下文 
  12.     const browserContext = await browser.createIncognitoBrowserContext(); 
  13.     // 在該上下文中創(chuàng)建一個(gè)新頁面 
  14.     const page2 = await browserContext.newPage(); 
  15.     page2.goto('https://www.baidu.com'); 
  16.  
  17. main(); 

3.3 設(shè)備模擬

經(jīng)常需要不同類型的機(jī)型的瀏覽結(jié)果,此時(shí)就可以采用設(shè)備模擬實(shí)現(xiàn),下面模擬一個(gè)iPhone X的設(shè)備的瀏覽器結(jié)果

  1. async function main() { 
  2.     // 啟動(dòng)瀏覽器 
  3.  
  4.     // 設(shè)備模擬:模擬一個(gè)iPhone X 
  5.     // user agent 
  6.     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'
  7.     // 視口(viewport)模擬 
  8.     await page1.setViewport({ 
  9.         width: 375, 
  10.         height: 812 
  11.     }); 
  12.      
  13.     // 訪問某頁面 
  14.  
  15. main(); 

3.4 獲取DOM節(jié)點(diǎn)

獲取DOM節(jié)點(diǎn)有兩種方式,一種方式是直接調(diào)用page所帶的原生函數(shù),另一種是通過執(zhí)行js代碼獲取。

  1. async function main() { 
  2.     // 啟動(dòng)chrome瀏覽器 
  3.     const browser = await puppeteer.launch({ 
  4.         // 指定該瀏覽器的路徑 
  5.         executablePath: chromiumPath, 
  6.         // 是否為無頭瀏覽器模式,默認(rèn)為無頭瀏覽器模式 
  7.         headless: false 
  8.     }); 
  9.  
  10.     // 在一個(gè)默認(rèn)的瀏覽器上下文中被創(chuàng)建一個(gè)新頁面 
  11.     const page1 = await browser.newPage(); 
  12.  
  13.     // 空白頁訪問該指定網(wǎng)址 
  14.     await page1.goto('https://www.baidu.com'); 
  15.  
  16.     // 等待title節(jié)點(diǎn)出現(xiàn) 
  17.     await page1.waitForSelector('title'); 
  18.  
  19.     // 用page自帶的方法獲取節(jié)點(diǎn) 
  20.     const titleDomText1 = await page1.$eval('title', el => el.innerText); 
  21.     console.log(titleDomText1);// 百度一下 
  22.  
  23.     // 用js獲取節(jié)點(diǎn) 
  24.     const titleDomText2 = await page1.evaluate(() => { 
  25.         const titleDom = document.querySelector('title'); 
  26.         return titleDom.innerText; 
  27.     }); 
  28.     console.log(titleDomText2); 
  29.  
  30. main(); 

3.5 監(jiān)聽請(qǐng)求和響應(yīng)

下面就來監(jiān)聽一下百度中某一js腳本的請(qǐng)求和響應(yīng),request事件是監(jiān)聽請(qǐng)求,response事件是監(jiān)聽響應(yīng)。

  1. async function main() { 
  2.     // 啟動(dòng)chrome瀏覽器 
  3.     const browser = await puppeteer.launch({ 
  4.         // 指定該瀏覽器的路徑 
  5.         executablePath: chromiumPath, 
  6.         // 是否為無頭瀏覽器模式,默認(rèn)為無頭瀏覽器模式 
  7.         headless: false 
  8.     }); 
  9.  
  10.     // 在一個(gè)默認(rèn)的瀏覽器上下文中被創(chuàng)建一個(gè)新頁面 
  11.     const page1 = await browser.newPage(); 
  12.  
  13.     page1.on('request', request => { 
  14.         if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') { 
  15.             console.log(request.resourceType()); 
  16.             console.log(request.method()); 
  17.             console.log(request.headers()); 
  18.         } 
  19.     }); 
  20.  
  21.     page1.on('response', response => { 
  22.         if (response.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') { 
  23.             console.log(response.status()); 
  24.             console.log(response.headers()); 
  25.         } 
  26.     }) 
  27.  
  28.     // 空白頁剛問該指定網(wǎng)址 
  29.     await page1.goto('https://www.baidu.com'); 
  30.  
  31. main(); 

3.6 攔截某一請(qǐng)求

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

  1. async function main() { 
  2.     // 啟動(dòng)chrome瀏覽器 
  3.     const browser = await puppeteer.launch({ 
  4.         // 指定該瀏覽器的路徑 
  5.         executablePath: chromiumPath, 
  6.         // 是否為無頭瀏覽器模式,默認(rèn)為無頭瀏覽器模式 
  7.         headless: false 
  8.     }); 
  9.  
  10.     // 在一個(gè)默認(rèn)的瀏覽器上下文中被創(chuàng)建一個(gè)新頁面 
  11.     const page1 = await browser.newPage(); 
  12.  
  13.     // 攔截請(qǐng)求開啟 
  14.     await page1.setRequestInterception(true);// true開啟,false關(guān)閉 
  15.     page1.on('request', request => { 
  16.         if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') { 
  17.             // 終止該請(qǐng)求 
  18.             request.abort(); 
  19.             console.log('該請(qǐng)求被終止!??!'); 
  20.         } 
  21.         else { 
  22.             // 繼續(xù)該請(qǐng)求 
  23.             request.continue(); 
  24.         } 
  25.     }); 
  26.  
  27.     // 空白頁訪問該指定網(wǎng)址 
  28.     await page1.goto('https://www.baidu.com'); 
  29.  
  30. main(); 

3.7 截圖

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

  1. async function main() { 
  2.     // 啟動(dòng)瀏覽器,訪問頁面的操作 
  3.      
  4.     // 截屏操作,使用Page.screenshot函數(shù) 
  5.     // 截取整個(gè)頁面:Page.screenshot函數(shù)默認(rèn)截取整個(gè)頁面,加上fullPage參數(shù)就是全屏截取 
  6.     await page1.screenshot({ 
  7.         path: '../imgs/fullScreen.png'
  8.         fullPage: true 
  9.     }); 
  10.  
  11.     // 截取屏幕中一個(gè)區(qū)域的內(nèi)容 
  12.     await page1.screenshot({ 
  13.         path: '../imgs/partScreen.jpg'
  14.         type: 'jpeg'
  15.         quality: 80, 
  16.         clip: { 
  17.             x: 0, 
  18.             y: 0, 
  19.             width: 375, 
  20.             height: 300 
  21.         } 
  22.     }); 
  23.  
  24.     browser.close(); 
  25.  
  26. main(); 

3.8 生成pdf

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

  1. async function main() { 
  2.     // 啟動(dòng)瀏覽器,訪問頁面的操作 
  3.      
  4.     // 根據(jù)網(wǎng)頁內(nèi)容生成pdf文件,使用Page.pdf——注意:必須在無頭模式下才可以調(diào)用 
  5.     await page1.pdf({ 
  6.         path: '../pdf/baidu.pdf' 
  7.     }); 
  8.  
  9.     browser.close(); 
  10.  
  11. main(); 

本文轉(zhuǎn)載自微信公眾號(hào)「執(zhí)鳶者」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系執(zhí)鳶者公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 執(zhí)鳶者
相關(guān)推薦

2021-09-13 09:28:10

PuppeteerNode 庫DevTools 協(xié)議

2021-05-27 12:10:42

前端puppeteer代碼

2023-12-06 07:36:27

前端開發(fā)

2015-08-26 14:18:25

Web前端工程師價(jià)值

2015-09-30 10:25:03

前端工程師

2014-12-23 14:55:23

前端

2016-01-28 11:18:09

卓越前端工程師

2015-08-17 10:32:06

前端工程師優(yōu)秀

2015-08-24 09:02:49

前端工程師

2018-11-15 15:55:44

前端工程師Web云計(jì)算

2010-01-13 10:53:51

Web前端工程師定位

2019-07-29 16:05:48

前端DockerNode.js

2016-09-22 16:14:45

前端設(shè)計(jì)Photoshop

2010-01-13 10:10:07

Web前端工程師

2015-03-16 16:01:40

Web前端前端工程師Web

2011-05-25 16:59:20

前端工程師

2019-12-18 10:30:24

前端開發(fā)技術(shù)

2019-06-24 09:40:17

前端前端工程師開發(fā)工具

2011-04-15 09:14:03

抄襲巨頭IT

2020-09-29 07:38:22

Python裝飾器框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)