前面寫(xiě)過(guò)的phantomJs定铜,研究幾天后發(fā)現(xiàn)phantomJs雖然在業(yè)內(nèi)有一定的影響力阳液,但后繼乏力,主要還是缺乏維護(hù)人員揣炕,導(dǎo)致項(xiàng)目依賴的chrome內(nèi)核版本太低帘皿,無(wú)人解決的BUG太多(1000+),現(xiàn)在這個(gè)環(huán)境已經(jīng)越來(lái)越滿足不了真實(shí)的前端模擬以及各種新的特性需求(比如高版本Chrome的執(zhí)行環(huán)境特性畸陡,比如JS執(zhí)行和渲染等都相差很大)鹰溜,GitHub參照:點(diǎn)擊這里。
谷歌瀏覽器在17年自行開(kāi)發(fā)了Chrome Headless特性丁恭,并與之同時(shí)推出了puppeteer奉狈,可以理解成我們?nèi)粘J褂玫腃hrome的無(wú)界面版本以及對(duì)其進(jìn)行操控的js接口套裝,官方介紹參照:點(diǎn)擊這里涩惑。
借助puppeteer仁期,我們實(shí)際上是通過(guò)調(diào)用Chrome DevTools開(kāi)放的接口與Chrome通信,Chrome DevTools的接口很復(fù)雜竭恬,但puppeteer對(duì)其進(jìn)行了封裝跛蛋,我們調(diào)用起來(lái)還是很方便的。寫(xiě)幾個(gè)簡(jiǎn)單例子:
Demo1:打開(kāi)百度痊硕,并保存截圖
下面代碼保存在 baidu.js中(當(dāng)然需要提前初始化package.json等操作赊级,默認(rèn)大家都了解的):
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'
? ? })
})()
通過(guò) node baidu.js 就可以將截圖保存下來(lái),下面是效果圖:
當(dāng)然上面的只是最簡(jiǎn)單的操作岔绸,涉及到的API也少理逊,查看完整API可以:點(diǎn)擊這里
再來(lái)豐富下上面的操作:
Demo2:iPhoneX模式打開(kāi)百度,并保存截圖
代碼如下盒揉,相比demo1其實(shí)只是多了幾行代碼晋被,也就是調(diào)用了 page.emulate方法按照給定設(shè)備對(duì)頁(yè)面的尺寸進(jìn)行了設(shè)定:
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'
? ? })
})()
截圖如下:
針對(duì)device設(shè)備的完整列表,可以參照源碼:點(diǎn)擊這里刚盈,(PS:大家都要學(xué)會(huì)找源碼羡洛,讀源碼,項(xiàng)目中經(jīng)常碰到引用插件的問(wèn)題藕漱,通過(guò)查找源碼可以加深對(duì)問(wèn)題的理解欲侮,才可能真正解決)
上面兩個(gè)例子都是比較簡(jiǎn)單的操作崭闲,只有加載頁(yè)面和截圖,沒(méi)有用戶交互操作威蕉,我們繼續(xù)
Demo3:iPhoneX模式打開(kāi)百度刁俭,搜索puppeteer關(guān)鍵字,跳轉(zhuǎn)到查詢結(jié)果頁(yè)面后韧涨,保存截圖
這個(gè)demo真正增加的步驟也就三個(gè):
找到 輸入文本框 并填充關(guān)鍵字 puppeteer薄翅;
找到 百度一下 按鈕并點(diǎn)擊;
等待頁(yè)面跳轉(zhuǎn)顯示查詢結(jié)果氓奈;
代碼如下:
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'
? ? })
})()
上面的加粗的三行代碼就對(duì)應(yīng)多出的三個(gè)步驟,需要留意的是鼎天,在PC直接訪問(wèn)百度和模擬iPhoneX訪問(wèn)百度拿到的文本框和按鈕的id是不同的舀奶,也就是說(shuō),百度并不是直接拿一個(gè)站點(diǎn)做mediaQuery之類(lèi)設(shè)置供PC和移動(dòng)端共享斋射,而是兩個(gè)完全不同的頁(yè)面育勺,這里不討論優(yōu)缺點(diǎn),如果大家想要在PC看iPhoneX訪問(wèn)的效果就要利用ChromeDevTools改下設(shè)置:
兩個(gè)紅色方框是設(shè)置的地方罗岖,藍(lán)色方框標(biāo)注兩個(gè)元素的id
最終截圖見(jiàn)下:
好了涧至,puppeteer的入門(mén)及實(shí)踐(1)就到此為止了,總結(jié)下桑包,puppeteer作為谷歌出品的前端利器南蓬,想象空間是很大的,在爬蟲(chóng)哑了、測(cè)試自動(dòng)化等方面都可以很好勝任赘方,跟其他測(cè)試工具不同,不再是模擬谷歌執(zhí)行引擎再去渲染弱左,而是一個(gè)真正在運(yùn)行的瀏覽器窄陡,只是移除了真實(shí)的界面渲染。作為一個(gè)入門(mén)課程拆火,很多細(xì)節(jié)都沒(méi)詳述跳夭,比如可以通過(guò)傳參 headless: false 讓puppeteer操作Chrome的過(guò)程可視化,各步驟可以指定間隔時(shí)間们镜,還有插件可以錄制等币叹,這些更精彩的留待后面再寫(xiě)。
文中所有DEMO源碼參照:
https://github.com/wu0792/puppeteer_01