做者:林淙源
html
導語: Most things that you can do manually in the browser can be done using Puppeteer!前端
puppeteer 翻譯是操縱木偶的人,利用這個工具,咱們能作一個操縱頁面的人。puppeteer是一個nodejs的庫,支持調用Chrome的API來操縱Web,相比較Selenium或是PhantomJs,它最大的特色就是它的操做Dom能夠徹底在內存中進行模擬既在V8引擎中處理而不打開瀏覽器,並且關鍵是這個是Chrome團隊在維護,會擁有更好的兼容性和前景。node
1.利用網頁生成PDF、圖片
2.爬取SPA應用,並生成預渲染內容(即「SSR」 服務端渲染)
3.能夠從網站抓取內容
4.自動化表單提交、UI測試、鍵盤輸入等
5.幫你建立一個最新的自動化測試環境(chrome),能夠直接在此運行測試用例
6.捕獲站點的時間線,以便追蹤你的網站,幫助分析網站性能問題jquery
安裝 puppeteergit
yarn add puppeteer # or "npm i puppeteer" 複製代碼
可能會遇到 沒法下載Chromium 問題github
是由於在執行安裝的過程當中須要執行install.js,這裏會下載Chromium,官網建議是進行跳過,咱們能夠執行 —ignore-scripts 忽略這個js執行chrome
./node/npm i --save puppeteer --ignore-scripts
複製代碼
接下來咱們須要去下載Chromium,windows的版本我這裏已經下載好了,直接解壓縮附件中的到 node_modules/puppeteer中就能夠了。npm
執行下,咱們建立一個文件index.js,文件內容json
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://y.qq.com'); await page.screenshot({path: 'yqq.png'}); browser.close(); })(); 複製代碼
這段代碼會打開 y.qq.com 並截圖,咱們運行windows
node index.js
複製代碼
若是看到目錄下有生成圖片y.qq.png的話,恭喜你,咱們能夠開始繼續往下學習puppeteer了。
這裏測試的功能是自動拉登陸購買一張數字專輯,並在購買成功後跳轉到銘牌頁,先看下整個流程吧。
首先咱們先建立一個設備,文檔中(github.com/GoogleChrom…)
咱們能看到,默認支持的設備數量仍是不少的,除了這些默認的設備以外,咱們還能夠自定義本身的設備,後面在調用emulate方法時會提到:
咱們這裏暫時先建立系統提供的iphone6設備,完了咱們定義一個延時的timeout函數
const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); const iPhone = devices['iPhone 6']; let timeout = function (delay) { return new Promise((resolve, reject) => { setTimeout(() => { try { resolve(1) } catch (e) { reject(0) } }, delay); }) } 複製代碼
接下來咱們建立一個瀏覽器實例,並打開一個頁面,細心的你必定發如今建立瀏覽器的時候咱們傳了headless參數,若是設爲true的話就能能夠在不打開外部瀏覽器的狀況下徹底利用v8引擎來進行頁面的測試,簡單說就是頁面以及Dom徹底在內存中,就連瀏覽器事件也是在內存中去模擬觸發。
const browser = await puppeteer.launch({ headless:false //這裏我設置成false主要是爲了讓你們看到效果,設置爲true就不會打開瀏覽器 }); const page = await browser.newPage(); 複製代碼
建立好瀏覽器實例以後咱們須要讓頁面模擬成iphone6,這裏的emulate函數的參數你也能夠自定義參數
await page.emulate(iPhone); 參數: { 'name': 'Galaxy S5', //設備名 'userAgent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36', //UA 'viewport': { 'width': 360,//屏幕寬度 'height': 640,//屏幕高度 'deviceScaleFactor': 3,//縮放比例 'isMobile': true,//是不是移動設備 'hasTouch': true,//是否支持touch事件 'isLandscape': false//是否橫屏 } } 複製代碼
好接下來咱們就能夠寫咱們的測試步驟了。
第一步:咱們打開頁面,考慮到有數據須要異步加載,咱們在延遲1000ms後調用screenshot方法截圖留做日誌。
console.log("進入頁面"); await page.goto('https://y.qq.com/m/digitalbum/gold/index.html?_video=true&id=2210323&g_f=tuijiannewupload#index/fans'); await timeout(1000); await page.screenshot({ path: '1.png' }); 複製代碼
第二步:模擬觸發點擊 當即購買按鈕,這時候會由於沒有登陸態而打開QQ登陸。
console.log("點擊當即購買按鈕"); await page.tap('.js_sale_buyalbum'); await page.screenshot({ path: '2.png' }); 複製代碼
第三步:在輸入框中輸入賬號密碼,模擬輸入須要咱們先調用tap方法模擬點擊輸入框,tap參數就是元素selector,再用type方法進行輸入,輸入完了以後在模擬點擊登陸按鈕,登陸完了以後咱們延遲一段時間截圖,順利的話咱們就能從新回到以前的售賣頁首頁,而底下usrbar由於有了登陸態也展現了出來。
console.log("登陸"); await page.tap("#u"); //直接操做dom選擇器,是否是很方便 await page.type("521017853"); await page.tap("#p"); await page.type("*********");//這裏密碼就不展現了哈 await page.tap("#go"); await timeout(3000); await page.screenshot({ path: '3.png' }); console.log("登陸成功"); 複製代碼
第四步:跟第一步同樣,點擊當即購買按鈕,這裏會出現一個購買選擇浮層,而後咱們點擊當即支付以後須要加載米大師,故這裏咱們延遲5000ms。
//點擊購買 console.log("點擊當即購買按鈕"); await page.tap('.js_sale_buyalbum'); await page.screenshot({ path: '4.png' }); console.log("點擊支付浮層上的當即支付"); await page.tap(".js_buyalbum_pay"); await timeout(5000); 複製代碼
第五步:在拉起米大師支付浮層以後,咱們須要去點擊提示中的肯定按鈕,因爲米大師是在iframe中打開的,因此咱們須要先獲取到咱們當前頁frame,這個能夠調用剛建立的頁面實例page的mainFrame()方法便可得到,若是咱們須要獲取子frame的話也只須要調用childFrames來進行獲取。在獲取到米大師對應的frame以後就能夠調用midas_frame.$(selector)類jquery的方法進行元素的獲取,以後再模擬點擊。
console.log("進入 米大師支付浮層") await page.screenshot({ path: '5.png' }); let $frame = page.mainFrame(); let midas_frame = $frame.childFrames()[0];//獲取到midas對應的frame console.log("點擊肯定 米大師支付浮層測試環境提示 的確認按鈕"); let $dom = await midas_frame.$(".fusion-pm-fl-wrapper .fpm-default"); await $dom.tap(); await page.screenshot({ path: '6.png' }); 複製代碼
第六步:點擊Q幣支付
console.log("點擊 米大師支付浮層 確認支付按鈕"); $dom = await midas_frame.$("#wrap .fpm-default"); await $dom.tap(); await timeout(5000); await page.screenshot({ path: '7.png' }); 複製代碼
第七步:點擊完成進入銘牌頁,測試完畢,關閉瀏覽器實例
console.log("點擊 米大師支付浮層 支付完成"); $dom = await midas_frame.$("#wrap .btn-primary"); await $dom.tap(); await timeout(2000); console.log("已購銘牌頁"); await page.screenshot({ path: '8.png' }); browser.close(); 複製代碼
最後在項目目錄中,咱們看到,各個步驟的截圖都已生成。
Trace API 主要是利用Chrome Performance,生成頁面性能追蹤的文件 trace.json,在Chrome 開發者工具中上傳該文件,就能夠對裏面的火焰圖去作分析。
事例代碼:
const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); const iPhone = devices['iPhone 6']; (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.emulate(iPhone); await page.tracing.start({path: './trace.json'}); await page.goto('https://y.qq.com/m/digitalbum/gold/index.html?_video=true&id=2210323&g_f=tuijiannewupload#index/fans'); await page.tracing.stop(); browser.close(); } catch (e) { console.log(e.message); } })(); 複製代碼
首先,這段代碼執行的是模擬iphone6打開林俊杰的《丹寧執着》數專售賣頁,並進行性能的分析。主要使用 tracing.start,stop生成trace.json文件
trace.json
接下來咱們打開Chrome的開發者工具,進入到Performance欄目下,把剛纔的trace.json拖上去就能看到數據了
經過上面兩個例子,咱們看到了puppeteer能夠作UI自動化測試和頁面性能檢測,其實他的功能遠遠不止於此,好比還能夠作爬蟲,去爬取github的文章或是掘金上的博客,總之,本身也是初次嘗試,確定會有更多的功能可以被挖掘出來,但願你們多多交流。
WebRTC 前端實時通訊技術
全面瞭解 React License
雲MongoDB優化讓LBS服務性能提高十倍
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處原文連接:https://cloud.tencent.com/community/article/529168