爬蟲利器-Puppeteer初探

模擬瀏覽器操作神器Puppeteer初探

介紹

??剛接觸到puppeteer征讲,并不是用來做爬蟲震桶,只是想做一個(gè)后臺數(shù)據(jù)推送及性能數(shù)據(jù)抓取的功能竣况,需要模擬登陸內(nèi)部系統(tǒng)爬取數(shù)據(jù)截圖鹊杖。一開始想到利用很多方案坯沪,像wkhtmltopdf, phantomjs等等绿映,他們都是類瀏覽器的環(huán)境,因?yàn)橹笆褂眠^,都知道他們或多或少都存在些問題叉弦。再后來發(fā)現(xiàn)了headless丐一,谷歌的無頭瀏覽器服務(wù),這個(gè)最接近真實(shí)瀏覽器的東西(應(yīng)該說就是個(gè)瀏覽器吧)淹冰,然后決定采用headless钝诚,網(wǎng)上最多的是采用lighthouse作為操作headless的nodejs接口工具,后來看到puppeteer,和lighthouse差不多榄棵,但畢竟是谷歌團(tuán)隊(duì)自己維護(hù)的工具凝颇,當(dāng)然就選擇了它,后來看了看疹鳄,果然還是它用起來比較方便拧略。

??官方對于puppeteer的介紹(翻譯過來):

puppeteer由Chrome團(tuán)隊(duì)開發(fā)的Node庫。它提供了一個(gè)高級API來控制無頭(或完整)Chrome瘪弓。它與Phantom和NightmareJS等其他自動化測試庫類似垫蛆,但它只適用于最新版本的Chrome。
除此之外腺怯,Puppeteer還可用于輕松截取屏幕截圖袱饭,創(chuàng)建PDF绷杜,導(dǎo)航頁面以及獲取有關(guān)這些頁面的信息庙睡。如果您想快速自動化瀏覽器測試创橄,我建議使用該庫耙饰。它隱藏了DevTools協(xié)議的復(fù)雜性歇竟,并負(fù)責(zé)啟動Chrome的調(diào)試實(shí)例等冗余任務(wù)>

??看起來很強(qiáng)大對不對玉组,實(shí)時(shí)上除了無頭模式耍目,Puppeteer也可以操作真實(shí)瀏覽器進(jìn)行工作房交,你會發(fā)現(xiàn)它除了可以做完美的爬蟲之外帜篇,對于自動化的ui測試也是利器糙捺。目前也有了中文文檔,使用起來也是極其方便的

截圖

讓我們先來看一下它的api,首先是puppteer對象笙隙,用于啟動一個(gè)Chromium實(shí)例洪灯,例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.google.com');
  // 其他操作...
  await browser.close();
});

??上圖實(shí)際是打開了一個(gè)瀏覽器應(yīng)用,lauch方法支持一個(gè)對象類型的參數(shù)竟痰,其中可以指定headless為true還是false,當(dāng)指定為true是签钩,可以觀察到實(shí)際行為,在我們測試的時(shí)候還是很有用處的凯亮,當(dāng)我們設(shè)置為true是可以觀察到边臼,browser對象針對的是整個(gè)瀏覽器窗口,而page對象針對的是每個(gè)tab頁簽假消,當(dāng)關(guān)閉browser對象時(shí)柠并,所有page對象都會被銷毀,如果想要單獨(dú)銷毀page對象可以調(diào)用page.close();
??在實(shí)際應(yīng)用中,page對象是我們最常用的對象臼予,下面是使用page對象打開一個(gè)頁面并進(jìn)行截圖的例子:

const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.baidu.com');
  // 截圖...
  await page.screenshot({path:'xx/xx.png',type:'png',quality:100,fullPage:true});
  await browser.close();
});

這里介紹下截圖的幾個(gè)參數(shù):

  • path:圖片存儲路徑
  • type: 圖片格式鸣戴,默認(rèn)png
  • quality: 圖片質(zhì)量0-100的值,png格式無效
  • fullpage: 是否截取整個(gè)頁面粘拾,如果不設(shè)置窄锅,截取的是窗口打開部分,并不是全頁面缰雇,默認(rèn)打開的窗口是800x600大小入偷,如果想截取更完美的大小需要調(diào)整視窗大小,通過設(shè)置launch的defaultViewport參數(shù)械哟。

性能數(shù)據(jù)獲取

puppteer也支持我們在打開頁面時(shí)進(jìn)行一些性能數(shù)據(jù)的采集疏之,page.metrics()方法可以幫我們獲取到頁面打開過程中的性能參數(shù):

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.target.com');
  // 獲取頁面性能數(shù)據(jù)...
  const result = await  page.metrics();
  console.log(result);
  await browser.close();
});

返回結(jié)果包括:

  • Timestamp <number> 時(shí)間點(diǎn)(when the metrics sample was taken)
  • Documents <number> 頁面的documents數(shù)量。
  • Frames <number> 頁面的iframe數(shù)量暇咆。
  • JSEventListeners <number> 頁面的js事件數(shù)量锋爪。
  • Nodes <number> 頁面的dom節(jié)點(diǎn)數(shù)量。
  • LayoutCount <number> 整頁面或部分頁面的布局?jǐn)?shù)量爸业。
  • RecalcStyleCount <number> 頁面樣式重新計(jì)算數(shù)量其骄。
  • LayoutDuration <number> 頁面布局總時(shí)間。
  • RecalcStyleDuration <number> 頁面樣式重新計(jì)算總時(shí)間扯旷。
  • ScriptDuration <number> 頁面js代碼執(zhí)行總時(shí)間拯爽。
  • TaskDuration <number> 頁面任務(wù)執(zhí)行總時(shí)間。
  • JSHeapUsedSize <number> 頁面占用堆內(nèi)存大小薄霜。
  • JSHeapTotalSize <number> 總的頁面堆內(nèi)存大小某抓。
    還有另外一個(gè)api,用于獲取我們平時(shí)利用瀏覽器觀察頁面加載性能的performance視圖惰瓜,它會生成和谷歌瀏覽器中profile.json一樣的一個(gè)json數(shù)據(jù),我們可以導(dǎo)入瀏覽器中查看


    屏幕快照 2019-04-13 22.14.01.png

相關(guān)代碼:

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.tracing.start({path: 'trace.json'});
  await page.goto('https://www.target.com');
  await page.tracing.stop();
  await browser.close();
  
});

我們拿到.json文件后也可以訪問DevTools Timeline Viewer導(dǎo)入去查看頁面加載的詳細(xì)信息汉矿。

那么對于性能數(shù)據(jù)來說崎坊,我們最常用的手機(jī)api就是performance.timing這個(gè)對象了,那么我們?nèi)绻趐uppteer中去獲取并收集數(shù)據(jù)呢洲拇?下面看一個(gè)例子:

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.target.com',{
  waitUntil:'networkidle0'
  });
  const timing = await page.evaluate(() => (window.performance.timing.toJSON()));
  console.log(timing);
  await browser.close();
  
});

上面的goto方法內(nèi)我加了一個(gè)參數(shù)networkidle0奈揍,意思是不再有任何網(wǎng)絡(luò)連接時(shí)觸發(fā)(至少500毫秒后)后才算頁面跳轉(zhuǎn)完成,這么做是為了等頁面完全加載結(jié)束赋续,獲得最準(zhǔn)確的數(shù)據(jù)男翰,在evaluate方法內(nèi)可以使用page對象內(nèi)的上下文,也就是當(dāng)前頁面的dom對象都是可以使用的纽乱,這樣就拿到了timing數(shù)據(jù)蛾绎。

最后

除此之外,也可以利用puppteer的Coverage對象獲取js以及css的代碼覆蓋率,這里就不做過多介紹了租冠,感興趣的同學(xué)可以自行研究鹏倘。
參考文章:https://developers.google.com/web/updates/2017/04/headless-chrome
???????https://zhaoqize.github.io/puppeteer-api-zh_CN/#/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市顽爹,隨后出現(xiàn)的幾起案子纤泵,更是在濱河造成了極大的恐慌,老刑警劉巖镜粤,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捏题,死亡現(xiàn)場離奇詭異,居然都是意外死亡肉渴,警方通過查閱死者的電腦和手機(jī)涉馅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來黄虱,“玉大人稚矿,你說我怎么就攤上這事∧砥郑” “怎么了晤揣?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長朱灿。 經(jīng)常有香客問我昧识,道長,這世上最難降的妖魔是什么盗扒? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任跪楞,我火速辦了婚禮,結(jié)果婚禮上侣灶,老公的妹妹穿的比我還像新娘甸祭。我一直安慰自己,他們只是感情好褥影,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布池户。 她就那樣靜靜地躺著,像睡著了一般凡怎。 火紅的嫁衣襯著肌膚如雪校焦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天统倒,我揣著相機(jī)與錄音寨典,去河邊找鬼。 笑死房匆,一個(gè)胖子當(dāng)著我的面吹牛耸成,可吹牛的內(nèi)容都是我干的报亩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼墓猎,長吁一口氣:“原來是場噩夢啊……” “哼捆昏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毙沾,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤骗卜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后左胞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寇仓,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年烤宙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遍烦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡躺枕,死狀恐怖服猪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拐云,我是刑警寧澤罢猪,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站叉瘩,受9級特大地震影響膳帕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜薇缅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一危彩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泳桦,春花似錦汤徽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梧奢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間演痒,已是汗流浹背亲轨。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸟顺,地道東北人惦蚊。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓器虾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蹦锋。 傳聞我的和親對象是個(gè)殘疾皇子兆沙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355