Phantomjs、Selenium之后浪Puppeteer
隨著PhantomJS的bug越來越多,也無人維護后,谷歌推出的Puppeteer已達60Kstar,替代是毫無疑問。如果不考慮瀏覽器兼容問題,Puppeteer的簡潔的接口,更簡單的Js語法,做自動化測試也是不錯的方案。

Puppeteer是什么?
Puppeteer官網:https://pptr.dev/?建議FQ訪問。
Github地址:https://github.com/puppeteer/puppeteer
Puppeteer是一個Node庫,它提供了高級API來通過DevTools協議控制Chrome或Chromium,簡單理解成我們日常使用的Chrome的無界面版本,可以使用js接口進行進行操控。意味凡是Chrome瀏覽器能干的事情,Puppeteer都能出色的完成,比如:
生成頁面的屏幕截圖和PDF。
爬取SPA(單頁應用程序)并生成預渲染的內容(即“ SSR”(服務器端渲染)),能抓取到所有能在頁面正常渲染的內容,無論是html還是基于js的異步加載。
自動執行表單提交,UI測試,鍵盤輸入,模擬用戶登錄等。
創建最新的自動化測試環境。使用最新的JavaScript和瀏覽器功能,直接在最新版本的Chrome中運行測試。
捕獲時間線跟蹤 您的網站以幫助診斷性能問題。
測試Chrome擴展程序。
安裝Puuueteer
依賴npm,建議使用cnpmnpm?i?puppeteer或者yarn?add?puppeteer
安裝好后,會自動安裝Chromium,大約100多M,目前puppeteer的版本已到3.0.2。
Puppeteer API結構
Puppeteer API是分層的,和瀏覽器保持一致,如圖所示(褪色實體當前未在Puppeteer中表示):
Puppeteer API結構
Puppeteer使用DevTools協議與瀏覽器通信.
Browser 實例可以擁有多個瀏覽器上下文。
BrowserContext 實例定義了一個瀏覽會話,并且可以擁有多個頁面。
Page至少有一個框架:主框架。iframe可能還會創建其他框架或框架 標簽。
Frame具有至少一個執行上下文-默認執行上下文-在其中執行框架的JavaScript。框架可能具有與擴展關聯的其他執行上下文.
Worker具有單個執行上下文,并有助于與WebWorkers進行交互.
Puppeteer 入門教程和實踐
async/await語法
Puppeteer 官方推薦的是使用高版本 Node 的 async/await 語法
const?puppeteer?=?require('puppeteer'); (async?()?=>?{ ??const?browser?=?await?puppeteer.launch(); ??const?page?=?await?browser.newPage(); ??await?page.goto('https://www.baidu.com');?//打開一個網頁 ??//?執行其他腳步... ??await?browser.close(); })();
網站截圖:
const?puppeteer?=?require('puppeteer'); ?const?iPhone?=?puppeteer.devices['iPhone?8'];?//指定為手機端 ?(async?()?=>?{ ???//const?browser?=?await?puppeteer.launch(); ???const?browser?=?await?puppeteer.launch({ ?????headless:?false?//可以看到打開瀏覽器效果,默認值true ???});?? ???const?page?=?await?browser.newPage(); ???await?page.emulate(iPhone); ???await?page.goto('https://www.baidu.com'); ???//quality?指定照片質量0-100,不支持png格式圖片 ???await?page.screenshot({ ???????path:?'baidu.jpg', ???????quality:?100, ???????fullPage:?true ???}); ???await?browser.close(); ?})();
生成PDF:
const?puppeteer?=?require('puppeteer'); ??(async?()?=>?{ ????const?browser?=?await?puppeteer.launch(); ????const?page?=?await?browser.newPage(); ????//waitUntil:networkidle2?會一直等待,直到頁面加載后同時沒有存在?2?個以上的資源請求,這個種狀態持續至少?500?ms ????await?page.goto('https://www.baidu.com',?{waitUntil:?'networkidle2'}); ????await?page.pdf({path:?'baidu.pdf',?format:?'A4'}); ????await?browser.close(); ??})();
測試Chrome擴展程序:
Chrome / Chromium中的擴展程序當前僅在non-headless模式下工作
const?puppeteer?=?require('puppeteer'); (async?()?=>?{ ??const?pathToExtension?=?require('path').join(__dirname,?'my-extension'); ??const?browser?=?await?puppeteer.launch({ ????headless:?false, ????args:?[ ??????`--disable-extensions-except=${pathToExtension}`, ??????`--load-extension=${pathToExtension}` ????] ??}); ??const?targets?=?await?browser.targets(); ??const?backgroundPageTarget?=?targets.find(target?=>?target.type()?===?'background_page'); ??const?backgroundPage?=?await?backgroundPageTarget.page(); ??//?Test?the?background?page?as?you?would?any?other?page. ??await?browser.close(); })();
高級版抓圖淘寶網站
const?puppeteer?=?require('puppeteer'); ?(async()?=>?{ ???//?啟動Chromium ???const?browser?=?await?puppeteer.launch({ ?????ignoreHTTPSErrors:?true, ?????headless:?false, ?????args:?['--no-sandbox'] ???}); ???//?打開新頁面 ???const?page?=?await?browser.newPage(); ???//?設置頁面分辨率 ???await?page.setViewport({ ?????width:?1920, ?????height:?1080 ???}); ?let?request_url?=?'https://www.taobao.com'; ???//?訪問 ???await?page.goto(request_url,?{ ?????waitUntil:?'domcontentloaded' ???}).catch(err?=>?console.log(err)); ???await?page.waitFor(1000); ???let?title?=?await?page.title(); ???console.log(title); ?//?網頁加載最大高度 ???const?max_height_px?=?20000; ???//?滾動高度 ???let?scrollStep?=?1080; ???let?height_limit?=?false; ???let?mValues?=?{ ?????'scrollEnable':?true, ?????'height_limit':?height_limit ???}; ?while?(mValues.scrollEnable)?{ ?mValues?=?await?page.evaluate((scrollStep,?max_height_px,?height_limit)?=>{ ?if?(document.scrollingElement)?{ ?????let?scrollTop?=?document.scrollingElement.scrollTop; ?????document.scrollingElement.scrollTop?=?scrollTop?+?scrollStep;?if?(null?!=?document.body?&&?document.body.clientHeight?>?max_height_px)?{???height_limit?=?true;?}?else?if?(document.scrollingElement.scrollTop?+?scrollStep?>?max_height_px)?{???height_limit?=?true;?}?let?scrollEnableFlag?=?false;?if?(null?!=?document.body)?{???scrollEnableFlag?=?document.body.clientHeight?>?scrollTop?+?1081?&&?!height_limit;?}?else?{???scrollEnableFlag?=?document.scrollingElement.scrollTop?+?scrollStep?>?scrollTop?+?1081?&&?!height_limit;?}?return?{???'scrollEnable':?scrollEnableFlag,???'height_limit':?height_limit,???'document_scrolling_Element_scrollTop':?document.scrollingElement.scrollTop?}; ?} ?}, ?scrollStep,?max_height_px,?height_limit); ?????await?sleep(800); ???} ?try?{ ?????await?page.screenshot({ ???????path:?"taobao1.jpg", ???????quality:?10, ???????fullPage:?true ?????}).catch(err?=>?{ ???????console.log('截圖失敗'); ???????console.log(err); ?????}); ?????await?page.waitFor(5000); ?}?catch?(e)?{ ?????console.log('執行異常'); ???}?finally?{ ?????await?browser.close(); ???} ?})(); ?//延時函數 ?function?sleep(delay)?{ ???return?new?Promise((resolve,?reject)?=>?{ ?????setTimeout(()?=>?{ ???????try?{ ?????????resolve(1) ???????}?catch?(e)?{ ?????????reject(0) ???????} ?????},?delay) ???}) ?}
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。