puppeteer介紹(一)爬蟲,性能,注入

Puppeteer 谷歌開發是一個 Node 庫,它提供了一個高級 API 來經過 DevTools 協議控制 Chromium 或 Chrome。Puppeteer 默認以 headless 模式運行,可是能夠經過修改配置文件運行「有頭」模式。javascript

能作啥?css

  • 生成頁面 PDF,截圖。
  • 抓取單頁應用執行並渲染
  • 自動提交表單,進行 UI 測試,鍵盤輸入等。
  • 建立一個時時更新的自動化測試環境。
  • 用來幫助分析性能問題。

介紹

Puppeteer API 是分層次的,反映了瀏覽器結構html

這張圖須要瞭解一下,便是puppeteer的結構,也是代碼的順序結構;java

// 瀏覽器實例
const puppeteer = require('puppeteer');
// 啓動 返回 browser
const browser = await puppeteer.launch();
// 返回 page
const page = await browser.newPage();
// 跳轉
await page.goto('https://www.baidu.com/');
// 返回page的frame
const frame = await page.mainFrame();
// 當前頁面的url https://www.baidu.com/
console.log(frame.url());
// 關閉
await browser.close();
複製代碼
  • Puppeteer 使用 DevTools 協議 與瀏覽器進行通訊。
  • Browser 實例能夠擁有瀏覽器。
  • BrowserContext 瀏覽器上下文。
  • Page 至少有一個框架:主框架。 可能還有其餘框架由 iframe 或 框架標籤 建立。
  • frame 至少有一個執行上下文 - 默認的執行上下文 - 框架的 JavaScript 被執行。 一個框架可能有額外的與 擴展 關聯的執行上下文。
  • Worker 具備單一執行上下文,而且便於與 WebWorkers 進行交互。

安裝

// 安裝puppeteer,若是報錯改用 cnpm 安裝
cnpm install puppeteer --save
複製代碼

經常使用函數

Puppeteer返回的大部分是Promise支持一下async/await會很方便; 每一個功能方法都有不少參數配置,先列舉部分git

瀏覽器操做、打開頁面

上方代碼內容github

跳轉地址

await page.goto('https://google.com/', {
    // 配置項 等待網絡狀態爲空閒的時候才繼續執行
    waitUntil: 'networkidle'
});
複製代碼

生成PDF,截圖

await page.screenshot({ path: "download/example.png" });
await page.pdf({ 
    path: "download/example_pdf.pdf',
    format: "A4"
});
複製代碼

等待

waitFor: 參數能夠是<string|number|function> 選擇器, 方法 或者 超時時間chrome

// 等待1s
await page.waitFor(1000);
// 等待元素加載完成
await page.waitForSelector("#id");
複製代碼

選擇器

  • 返回的類型 ElementHandle 表示一個頁內的 DOM 元素;
  • 是繼承自 JSHandle。而 JSHandle 表示頁面內的 JavaScript 對象
  • 實際上是執行的document.querySelector,document.querySelectorAll
// 返回單個,若是多個返回第一個,沒有返回null
const ElementHandle = await page.$("#js_login_select")
// 返回多個,若是沒有返回[]
await page.$$(".js_login_select")
複製代碼

page.$eval(selector, pageFunction[, ...args])

此方法在頁面內執行 document.querySelector,而後把匹配到的元素做爲第一個參數傳給 pageFunctionnpm

// 獲取html
const html = await page.$eval("body", e => e.outerHTML);
console.log(html);
// 獲取id
const id = await page.$eval('#div',div => div.id );
//清空輸入框的值,獲取焦點
await page.$eval('#input',input => {
    input.focus();
    input.value = '';
})
複製代碼

evaluate

頁面實例上下文中執行的方法json

const dimensions = await page.evaluate(param => {
    alert("個人方法dimensions和" + param);
    return {
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight,
        deviceScaleFactor: window.devicePixelRatio
    };
}, "參數");
複製代碼

eval與evaluate區別

page.evaluate 意爲在瀏覽器環境執行腳本,可傳入第二個參數做爲句柄,而 page.$eval 則針對選中的一個 DOM 元素執行操做。api

注意:選擇器過濾後獲得的dom,都是經過執行querySelector或者querySelectorALl獲得的,因此頁面腳本能執行的方法屬性,均可以在這裏使用

-經常使用函數

性能分析

Puppetter固然能夠分析網站的性能,不過是建立一個能夠在Chrome DevTools中打開的跟蹤文件。

// 每一個瀏覽器一次只能激活一條跟蹤
await page.tracing.start({
    path: "download/trace.json",
    screenshots: true
});
// 須要關閉
await page.tracing.stop();
複製代碼

成功後會在path的位置生成.json的文件,裏面一堆的數字和變量~ 打開chrome瀏覽器的devtools,拖進performance中就OK了~

請求攔截

Puppeteer還能夠監聽不少事件,load,error,close等等,固然包括request,response

對頁面的圖片請求攔截,若是不是圖片後綴能夠找規則篩選

// 啓動 request
await page.setRequestInterception(true);
// 監聽request
page.on("request", interceptedRequest => {
    if (
        interceptedRequest.url().endsWith(".png") ||    interceptedRequest.url().endsWith(".jpg") ||
        interceptedRequest.url().includes(".jpg")
    ) {
        // 中斷
        interceptedRequest.abort();
    } else {
        interceptedRequest.continue();
    }
});
await page.goto("https://www.58pic.com/");
複製代碼

注入

  1. addScriptTag:注入一個指定src(url)或者代碼(content)的 script 標籤到當前頁面。
  2. addStyleTag:添加一個指定link(url)的 < link rel="stylesheet" > 標籤。 或者添加一個指定代碼(content)的 < style type="text/css" > 標籤。
await page.addScriptTag({ path: "public/javascripts/test.js" });
await page.addStyleTag({ path: "public/css/test.css" });
複製代碼

這樣不一樣站點,只須要注入不一樣的腳本爬取

模擬瀏覽器

關於模擬不一樣的手機,須要不一樣的參數,Puppeteer準備了不少,能夠直接拿來用,在puppeteer/DeviceDescriptors中

const page = await browser.newPage();
// 模擬機型
await page.emulate(iPhone);
複製代碼

相關文章
相關標籤/搜索