前面寫過的phantomJs,研究幾天后發現phantomJs雖然在業內有一定的影響力,但后繼乏力,主要還是缺乏維護人員,導致項目依賴的chrome內核版本太低,無人解決的BUG太多(1000+),現在這個環境已經越來越滿足不了真實的前端模擬以及各種新的特性需求(比如高版本Chrome的執行環境特性,比如JS執行和渲染等都相差很大),GitHub參照:點擊這里。
谷歌瀏覽器在17年自行開發了Chrome Headless特性,并與之同時推出了puppeteer,可以理解成我們日常使用的Chrome的無界面版本以及對其進行操控的js接口套裝,官方介紹參照:點擊這里。
借助puppeteer,我們實際上是通過調用Chrome DevTools開放的接口與Chrome通信,Chrome DevTools的接口很復雜,但puppeteer對其進行了封裝,我們調用起來還是很方便的。寫幾個簡單例子:
Demo1:打開百度,并保存截圖
下面代碼保存在 baidu.js中(當然需要提前初始化package.json等操作,默認大家都了解的):
const puppeteer = require('puppeteer');
(async () => {
? ? const browser = await puppeteer.launch({
? ? ? ? headless: true
? ? })
? ? const page = await browser.newPage()
? ? await page.goto('http://www.baidu.com')
? ? await page.screenshot({
? ? ? ? path: 'c:/temp/baidu.png'
? ? })
})()
通過 node baidu.js 就可以將截圖保存下來,下面是效果圖:
當然上面的只是最簡單的操作,涉及到的API也少,查看完整API可以:點擊這里
再來豐富下上面的操作:
Demo2:iPhoneX模式打開百度,并保存截圖
代碼如下,相比demo1其實只是多了幾行代碼,也就是調用了 page.emulate方法按照給定設備對頁面的尺寸進行了設定:
const devices = require('puppeteer/DeviceDescriptors')
const puppeteer = require('puppeteer');
(async () => {
? ? const browser = await puppeteer.launch({
? ? ? ? headless: true
? ? })
? ? const page = await browser.newPage()
? ? await page.emulate(devices['iPhone X'])
? ? await page.goto('http://www.baidu.com')
? ? await page.screenshot({
? ? ? ? path: 'c:/temp/baidu_iphone_X.png'
? ? })
})()
截圖如下:
針對device設備的完整列表,可以參照源碼:點擊這里,(PS:大家都要學會找源碼,讀源碼,項目中經常碰到引用插件的問題,通過查找源碼可以加深對問題的理解,才可能真正解決)
上面兩個例子都是比較簡單的操作,只有加載頁面和截圖,沒有用戶交互操作,我們繼續
Demo3:iPhoneX模式打開百度,搜索puppeteer關鍵字,跳轉到查詢結果頁面后,保存截圖
這個demo真正增加的步驟也就三個:
找到 輸入文本框 并填充關鍵字 puppeteer;
找到 百度一下 按鈕并點擊;
等待頁面跳轉顯示查詢結果;
代碼如下:
const devices = require('puppeteer/DeviceDescriptors')
const puppeteer = require('puppeteer');
(async () => {
? ? const browser = await puppeteer.launch({
? ? ? ? headless: true
? ? })
? ? const page = await browser.newPage()
? ? await page.emulate(devices['iPhone X'])
? ? await page.goto('http://www.baidu.com')
? ? await page.type('#index-kw', 'puppeteer')
? ? await page.click('#index-bn')
? ? await page.waitForNavigation({ timeout: 3000 })
? ? await page.screenshot({
? ? ? ? path: 'c:/temp/baidu_iphone_X_search_puppeteer.png'
? ? })
})()
上面的加粗的三行代碼就對應多出的三個步驟,需要留意的是,在PC直接訪問百度和模擬iPhoneX訪問百度拿到的文本框和按鈕的id是不同的,也就是說,百度并不是直接拿一個站點做mediaQuery之類設置供PC和移動端共享,而是兩個完全不同的頁面,這里不討論優缺點,如果大家想要在PC看iPhoneX訪問的效果就要利用ChromeDevTools改下設置:
兩個紅色方框是設置的地方,藍色方框標注兩個元素的id
最終截圖見下:
好了,puppeteer的入門及實踐(1)就到此為止了,總結下,puppeteer作為谷歌出品的前端利器,想象空間是很大的,在爬蟲、測試自動化等方面都可以很好勝任,跟其他測試工具不同,不再是模擬谷歌執行引擎再去渲染,而是一個真正在運行的瀏覽器,只是移除了真實的界面渲染。作為一個入門課程,很多細節都沒詳述,比如可以通過傳參 headless: false 讓puppeteer操作Chrome的過程可視化,各步驟可以指定間隔時間,還有插件可以錄制等,這些更精彩的留待后面再寫。
文中所有DEMO源碼參照:
https://github.com/wu0792/puppeteer_01