puppeteer 翻譯是操縱木偶的人,利用這個工具,咱們能作一個操縱頁面的人。puppeteer是一個nodejs的庫,支持調用Chrome的API來操縱Web,相比較Selenium或是PhantomJs,它最大的特調就是它的操做Dom能夠徹底在內存中進行模擬既在V8引擎中處理而不打開瀏覽器,並且關鍵是這個是Chrome團隊在維護,會擁有更好的兼容性和前景。javascript
yarn add puppeteer
# or "npm i puppeteer"
複製代碼
可能會遇到 沒法下載Chromium 問題html
是由於在執行安裝的過程當中須要執行install.js,這裏會下載Chromium,官網建議是進行跳過,咱們能夠執行 --ignore-scripts 忽略這個js執行./node/npm i --save puppeteer --ignore-scripts
複製代碼
接下來咱們須要去下載Chromium,進入node_modules的puppeteer目錄,打開package.json,就能找到對應的puppeteer的版本號前端
"puppeteer": {
"chromium_revision": "536395"
},
複製代碼
各版本下載地址參考:java
下載完了,在puppeteer目錄下增長.local-chromium目錄,若是是win64的系統則再建立win64-536395目錄,linux則建立linux-536395目錄,接下來把上面下載好的文件解壓進去就好啦。 接下來,咱們建立一個文件index.js,文件內容node
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();
})();
複製代碼
這段代碼會打開https://y.qq.com,並截圖,咱們運行jquery
node index.js
複製代碼
若是看到目錄下有生成圖片y.qq.png的話,恭喜你,咱們能夠開始繼續往下學習puppeteer了。linux
這裏測試的功能是自動拉登陸購買一張數字專輯,並在購買成功後跳轉到銘牌頁,先看下整個流程吧。git
首先咱們先建立一個設備,文檔中(https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js)咱們能看到,默認支持的設備數量仍是不少的,除了這些默認的設備以外,咱們還能夠自定義本身的設備,後面在調用emulate方法時會提到:github
咱們這裏暫時先建立系統提供的iphone6設備,完了咱們定義一個延時的timeout函數chrome
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的文章或是掘金上的博客,總之,本身也是初次嘗試,確定會有更多的功能可以被挖掘出來,但願你們多多交流。