Puppeteer v1.5.0 中文翻譯

最近用到了 Puppeteer 這個庫,既然用到了這個東西,順便也就把它的 API給看了一遍,爲了加深印象,在看的同時也就順便翻譯了一下,不過這API文檔的內容量仍是蠻大的,花費了好些時間纔看完,有些地方不知道怎麼翻譯比較好,因此也就沒翻譯,有的地方可能官方說得不怎麼詳細,我也加了一點主觀意見。javascript


Table of Contents

Overview

Puppeteer是一個經過 DevTools Protocol 來控制 Chromium 或者 Chrome的 Node庫,並提供了一些高級API。css

這些API層級分明,並能提現出瀏覽器的自身結構。html

NOTE 在下面這個圖例中,淺色實體表明的結構還沒有在 Puppeteer中實現。java

puppeteer overview

  • Puppeteer 使用 DevTools Protocol與瀏覽器進行通訊。
  • Browser 瀏覽器實例能夠包含多個瀏覽器上下文。
  • BrowserContext 用於保持瀏覽器session,一個瀏覽器上下文能夠包含多個頁面。
  • Page 一個Page最起碼包含一個frame,即 main frame,容許存在其餘的 frame,這些frame能夠用 [iframe]建立。
  • Frame 一個 Frame最起碼有一個 Javascript執行上下文環境,即默認的執行上下文環境。Frame容許存在額外附加的上下文環境
  • Worker 存在惟一的上下文環境,並可與 WebWorkers相互協做。

(圖例來源: link)node

Environment Variables

Puppeteer 須要明確的 environment variables 來協助其完成一系列操做,若是 Puppeteer沒有在打錢執行環境中發現這些環境變量,那麼將會直接從 npm config搜尋(忽略大小寫)。linux

  • HTTP_PROXY, HTTPS_PROXY, NO_PROXY - 定義了 HTTP proxy的相關配置,經常使用於下載或啓動 Chromium。
  • PUPPETEER_SKIP_CHROMIUM_DOWNLOAD - 用於指示 Puppeteer不要在安裝的過程當中下載 Chromium安裝包。
  • PUPPETEER_DOWNLOAD_HOST - 用於覆寫下載 Chromium安裝包的地址url。
  • PUPPETEER_CHROMIUM_REVISION - 在安裝階段,用於明確指示 Puppeteer下載安裝哪一個版本的 Chromium。

class: Puppeteer

Puppeteer模塊提供了一個用於啓動一個Chromium實例的方法。 下面的代碼展現了一種使用 Puppeteer來啓動 Chromium實例的典型例子:ios

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.google.com');
  // other actions...
  await browser.close();
});
複製代碼

puppeteer.connect(options)

  • options <Object>
    • browserWSEndpoint <string> a browser websocket endpoint to connect to.
    • ignoreHTTPSErrors <boolean> 在導航階段是否忽略 HTTPS錯誤,默認爲 false.
    • slowMo <number> 經過改變此值來減緩 Puppeteer的操做速度,單位是毫秒,當你想知道具體發生了什麼狀況的時候,此參數將會比較有用。
  • returns: <Promise<Browser>>:以 Promise的形式返回了一個 Browser實例對象。

此方法將會爲 Puppeteer 附加上一個 Chromium 實例。git

puppeteer.createBrowserFetcher([options])

  • options <Object>
    • host <string> 下載連接的host,默認爲 https://storage.googleapis.com
    • path <string> 下載連接的 path路徑,默認爲 <root>/.local-chromium, 這裏的root指的是是 puppeteer包的根目錄.
    • platform <string> 可能的選項有: mac, win32, win64, linux。默認是當前的環境平臺。
  • returns: <BrowserFetcher>

puppeteer.defaultArgs()

  • returns: <Array<string>> The default flags that Chromium will be launched with.

puppeteer.executablePath()

puppeteer.launch([options])

  • options <Object> 啓動瀏覽器時的配置,可能存在以下字段:
    • ignoreHTTPSErrors <boolean> 是否忽略在導航階段 HTTPS引起的錯誤,默認爲false
    • headless <boolean> 是否以一種 headless mode的模式來啓動瀏覽器。 只要devtools 選項不爲true,那麼此選項的默認值就是 true
    • executablePath <string> Chromium 或 Chrome 的運行路徑而不是安裝路徑。 若是 executablePath 是一個相對目錄, 那麼它應該是相對於 current working directory
    • slowMo <number> 經過改變此值來減緩 Puppeteer的操做速度,單位是毫秒,當你想知道具體發生了什麼狀況的時候,此參數將會比較有用。
    • args <Array<string>> 傳遞給瀏覽器實例的額外參數,這些參數的可選列表可見與此
    • ignoreDefaultArgs <boolean> 將會使 puppeteer.defaultArgs()失效。 屬於比較危險的選項,須要當心使用。默認爲 false
    • handleSIGINT <boolean> 程序終止信號,經過按下 Ctrl-C 來關閉瀏覽器進程,默認爲 true
    • handleSIGTERM <boolean> 程序結束信號,當接收到程序結束信號時,關閉瀏覽器進程,默認爲 true
    • handleSIGHUP <boolean> 程序掛起信號,當接收到程序掛起信號時,關閉瀏覽器進程,默認爲 true
    • timeout <number> 等待瀏覽器實例啓動的超時時間,單位爲 ms,默認是30000 (30秒),設置爲 0標識禁用此選項。
    • dumpio <boolean> 是否將瀏覽器的輸入、輸出流連通到控制檯的 process.stdoutprocess.stderr上。 默認爲 false.
    • userDataDir <string> User Data Directory所在路徑。
    • env <Object> 明確指示瀏覽器實例可用的環境變量,默認爲 process.env
    • devtools <boolean> 是否爲每一個標籤頁自動打開 DevTools面板,若是爲 true, 那麼 headless選項將被設置爲 false
    • pipe <boolean> 經過一個 pipe 而不是 WebSocket來連接瀏覽器實例,默認爲 false
  • returns: <Promise<Browser>> 一個返回 瀏覽器實例的 Promise.

此方法根據給定的參數來啓動一個瀏覽器實例,此瀏覽器實例將會在其 node.js主進程關閉時被銷燬。github

NOTE Puppeteer 也能夠直接用於控制 Chrome瀏覽器, 不過,只有當其控制的 Chrome瀏覽器的版本和其自己綁定的 Chromium版本一致時才能最大程度地發揮做用,若是版本不一致,可能沒法正常運行, 特別是當你使用了 executablePath 選項的時候。web

若是你更想使用 Google Chrome (而不是Chromium) 的話, a Chrome Canary or Dev Channel build is suggested.

在上面的 puppeteer.launch([options]) 選項中, 全部說起到 Chromium 的地方一樣適用於 Chrome。

你能夠在這篇文章中找到 Chromium 與 Chrome之間的不一樣之處, 這篇文章 則介紹了一些在 Linux平臺上的差別。

class: BrowserFetcher

BrowserFetcher 可以下載和管理不一樣版本的 Chromium。

BrowserFetcher 的方法能夠接收一個 版本號字符串,此版本號指定精確的 Chromium版本,例如 "533271",版本號列表能夠在 omahaproxy.appspot.com獲取。

下面這裏例子展現瞭如何經過 BrowserFetcher來下載一個特定版本的 Chromium,以及使用 Puppeteer來啓動這個 Chromium。

const browserFetcher = puppeteer.createBrowserFetcher();
const revisionInfo = await browserFetcher.download('533271');
const browser = await puppeteer.launch({executablePath: revisionInfo.executablePath})
複製代碼

NOTE BrowserFetcher沒法與其餘使用相同下載目錄的 BrowserFetcher實例同時運行。

browserFetcher.canDownload(revision)

  • revision <string> 檢查是否可用版本的版本號。
  • returns: <Promise<boolean>> 若是目標版本的瀏覽器能夠從目標 host上下載下來,則返回 true

此方法經過發起一個 HEAD request來檢查目標版本是否可用。

browserFetcher.download(revision[, progressCallback])

  • revision <string> 須要下載的瀏覽器的版本號.
  • progressCallback <function(number, number)> 此函數方法存在兩個參數:
    • downloadedBytes <number> 已經下載了多少字節
    • totalBytes <number> 一共有多少字節.
  • returns: <Promise<Object>> 當目標版本的瀏覽器正在被下載和提取的時候,返回一個 Promise 對象,此對象包含目標版本瀏覽器的一些信息。
    • revision <string> the revision the info was created from
    • folderPath <string> 提取所下載的瀏覽器包的目錄
    • executablePath <string> 目標版本的瀏覽器的運行目錄
    • url <string> 目標版本的瀏覽器的下載url
    • local <boolean> 目標版本的瀏覽器是否可在本地磁盤上獲取

此方法經過發起一個 GET請求來從目標 host下載指定版本的瀏覽器。

browserFetcher.localRevisions()

  • returns: <Promise<Array<string>>> 本地磁盤可獲取到的全部版本瀏覽器的列表。

browserFetcher.platform()

  • returns: <string> 返回 mac, linux, win32win64 中的其中一個。

browserFetcher.remove(revision)

  • revision <string> 須要刪除的版本。若是指定的版本的瀏覽器並無被下載下來,此方法將會拋出錯誤(此錯誤可用 catch捕獲)。
  • returns: <Promise> 當指定版本的瀏覽器被刪除後返回一個 Promise。

browserFetcher.revisionInfo(revision)

  • revision <string> 但願獲取相關信息的瀏覽器的版本號。

  • returns: <Object>

    • revision <string> 信息來源的版本號
    • folderPath <string> 提取所下載的瀏覽器包的目錄
    • executablePath <string> 目標版本的瀏覽器的運行目錄
    • url <string> 目標版本的瀏覽器的下載url
    • local <boolean> 目標版本的瀏覽器是否可在本地磁盤上獲取

    class: Browser

當 Puppeteer 鏈接上一個 Chromium實例的時候,將會puppeteer.launch 或者 puppeteer.connect方法產生一個 Browser。

下面是一個使用 Browser 來建立一個 Page的例子 :

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
});
複製代碼

下面是一個使用 Browser 來斷開鏈接和重連的例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  // Store the endpoint to be able to reconnect to Chromium
  const browserWSEndpoint = browser.wsEndpoint();
  // Disconnect puppeteer from Chromium
  browser.disconnect();

  // Use the endpoint to reestablish a connection
  const browser2 = await puppeteer.connect({browserWSEndpoint});
  // Close Chromium
  await browser2.close();
});
複製代碼

event: 'disconnected'

當 Puppeteer被從 Chromium實例上斷開時被觸發,包括以下幾種情形:

event: 'targetchanged'

當目標 url改變時觸發。

NOTE 包括在匿名瀏覽器上下文中目標URL改變。

event: 'targetcreated'

當目標被建立時觸發, 例如,當一個新頁面經過 window.open 或者 browser.newPage被打開時。

NOTE 包括在匿名瀏覽器上下文中目標的建立。

event: 'targetdestroyed'

目標被銷燬時觸發, 例如,當一個頁面關閉時。

NOTE 包括在匿名瀏覽器上下文中目標的銷燬。

browser.browserContexts()

返回一個包含全部已經被打開的瀏覽器上下文的數組。 在一個最新被建立的瀏覽器中,將會返回一個惟一的BrowserContext的實例。

browser.close()

關閉 Chromium以及它全部的頁面(若是存在被打開的頁面的話)。Browser 對象將會被銷燬,而且再也不可用。

browser.createIncognitoBrowserContext()

建立一個新的匿名瀏覽器上下文,這個匿名瀏覽器上下文不會與其餘瀏覽器上下文共享 cookies/cache。

const browser = await puppeteer.launch();
// Create a new incognito browser context.
const context = await browser.createIncognitoBrowserContext();
// Create a new page in a pristine context.
const page = await context.newPage();
// Do stuff
await page.goto('https://example.com');
複製代碼

browser.disconnect()

Disconnects Puppeteer from the browser, but leaves the Chromium process running. After calling disconnect, the Browser object is considered disposed and cannot be used anymore.

斷開 Puppeteer與 瀏覽器之間的鏈接,不過 Chromium進程依舊繼續運行。當調用了disconnect方法以後,Browser 對象將會被銷燬,而且再也不可用。

browser.newPage()

返回一個新的 Page Promise對象,Page將在一個默認的瀏覽器上下文中建立。

browser.pages()

  • returns: <Promise<Array<Page>>> resolve一個包含全部打開頁面的數組,不可見的頁面,例如 "background_page", 將不會包含在此數組中,你可使用 target.page()方法來獲取到(不可見頁面)。

browser.process()

  • returns: <?ChildProcess> 開啓一個瀏覽器主進程的子進程。若是瀏覽器實例是使用 puppeteer.connect 方法建立,那麼將會返回 null

browser.targets()

An array of all active targets inside the Browser. In case of multiple browser contexts, the method will return an array with all the targets in all browser contexts.

返回Browser實例中包含的全部的有效targets的一個數組,因爲可能存在多個瀏覽器上下文,因此此方法將會返回一個由全部瀏覽器上下文中的全部 targets梭組成的數組。

browser.userAgent()

NOTE 可使用 page.setUserAgent來改變瀏覽器的 user agent。

browser.version()

  • returns: <Promise<string>> 對於 headless Chromium來講,將返回一個相似於 HeadlessChrome/61.0.3153.0的字符串。 對於non-headless 瀏覽器來講, 將返回一個相似於 Chrome/61.0.3153.0的字符串。

NOTE 此方法返回的字符串格式可能會在未來的版本中發生變化。

browser.wsEndpoint()

  • returns: <string> 瀏覽器 websoket 的url。

此方法返回的 瀏覽器 websoket端口字符串格式如:ws://${host}:${port}/devtools/browser/<id>,此字符串可做爲puppeteer.connect方法的一個參數傳入。

You can find the webSocketDebuggerUrl from http://${host}:${port}/json/version. Learn more about the devtools protocol and the browser endpoint.

class: BrowserContext

BrowserContexts提供了一種操做多個獨立瀏覽器session的方法。當啓動一個瀏覽器的時候,將會同時產生一個BrowserContext,而且在這個 BrowserContext中,browser.newPage() 方法將會建立一個新頁面。

若是使用例如 window.open的方法建立了另外的頁面, the popup 將隸屬於父頁面的瀏覽器上下文。

Puppeteer容許經過 browser.createIncognitoBrowserContext() 方法來建立匿名瀏覽器上下文,匿名瀏覽器上下文不會向磁盤中記錄任何瀏覽的內容。

// 建立匿名瀏覽器上下文
const context = await browser.createIncognitoBrowserContext();
// 在上下文中建立頁面
const page = await context.newPage();
// ... do stuff with page ...
await page.goto('https://example.com');
// Dispose context once it's no longer needed.
await context.close();
複製代碼

event: 'targetchanged'

當瀏覽器上下文中的某個target url改變時觸發。

event: 'targetcreated'

當瀏覽器上下文中建立了一個新target時觸發,例如,當使用 window.openbrowserContext.newPage方法建立一個新頁面的時候。

event: 'targetdestroyed'

當瀏覽器上下文中的某個target 被銷燬時觸發,例如當一個頁面被關閉時。

browserContext.browser()

瀏覽器上下文歸屬的瀏覽器實例。

browserContext.close()

關閉瀏覽器上下文。全部屬於此瀏覽器上下文的target都將會一同銷燬。

NOTE 只有匿名瀏覽器上下文能夠被關閉(也就是隻有經過 createIncognitoBrowserContext方法建立的匿名瀏覽器纔可使用此方法)。

browserContext.isIncognito()

  • returns: <boolean> 返回 BrowserContext 是不是匿名的。 瀏覽器的默認上下文是非匿名的。

NOTE 瀏覽器的默認瀏覽器上下文是不可關閉的。

browserContext.newPage()

在瀏覽器上下文中建立新頁面。

browserContext.targets()

瀏覽器上下文中的全部有效target(例如Page頁面)組成的一個數組。

class: Page

Page提供了一些能讓你操做 Chromium中標籤頁的方法。一個 Browser實例中可能包含多個 Page實例。

下面的例子展現瞭如何建立一個地址爲指定url的頁面,並將這個頁面保存爲一張圖片。

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'screenshot.png'});
  await browser.close();
});
複製代碼

使用 Node模塊EventEmitter的一些方法,咱們可以控制 Page類觸發的一些事件,例如 on once 或者 removeListener等。

下面的例子展現瞭如何監聽頁面的 load事件。

page.once('load', () => console.log('Page loaded!'));
複製代碼

使用 removeListener方法來移除監聽事件:

function logRequest(interceptedRequest) {
  console.log('A request was made:', interceptedRequest.url());
}
page.on('request', logRequest);
// Sometime later...
page.removeListener('request', logRequest);
複製代碼

event: 'close'

當頁面關閉的時候觸發。

event: 'console'

當頁面上的Javascript腳本調用一些相似於 console.logconsole.dir的 console API時觸發,除此以外,若是頁面上的腳本拋出錯誤或者警告一樣也會觸發。

The arguments passed into console.log appear as arguments on the event handler.

下面是一個監聽 console事件的例子:

page.on('console', msg => {
  for (let i = 0; i < msg.args().length; ++i)
    console.log(`${i}: ${msg.args()[i]}`);
});
page.evaluate(() => console.log('hello', 5, {foo: 'bar'}));
複製代碼

event: 'dialog'

當頁面上彈出 JavaScript對話框的時候觸發,例如 alert, prompt, confirm 或者 beforeunload。Puppeteer可以經過 Dialogaccept 或者 dismiss 方法來對此事件做出迴應。

event: 'domcontentloaded'

當 JavaScript 的DOMContentLoaded 事件被觸發時觸發。

event: 'error'

當頁面崩潰時觸發。

NOTE error 事件在 Node中具備特殊的含義,具體細節參見 error events

event: 'frameattached'

當一個 frame 被附加到主頁面上時觸發。

event: 'framedetached'

當一個 frame 從主頁面上分離(刪除)時觸發。

event: 'framenavigated'

當一個 frame 的url被定向到一個新的url上時觸發。

event: 'load'

當 JavaScript 的load 事件被觸發時觸發。

event: 'metrics'

  • <Object>
    • title <string> console.timeStamp 的 title
    • metrics <Object> Object containing metrics as key/value pairs. The values of metrics are of <number> type.一個包含 metrics key/value對的對象。metrics的值爲 number類型。

當頁面上的JavaScript腳本調用 cnosole.timeStamp時觸發。metrics的可選列表可見 page.metrics

event: 'pageerror'

  • <Error> The exception message

當頁面上出現未捕獲的異常時觸發。

event: 'request'

當頁面上發起一個請求的時候觸發。request對象是隻讀的,若是你想攔截並改造請求,參照 page.setRequestInterception

event: 'requestfailed'

當請求失敗時觸發,例如,請求超時。

event: 'requestfinished'

當請求完成時觸發。

event: 'response'

當頁面收到請求的響應時觸發。

event: 'workercreated'

當頁面上產生一個新的 WebWorker線程時觸發。

event: 'workerdestroyed'

當頁面上有 WebWorker線程結束時觸發。

page.$(selector)

此方法在頁面上使用了 document.querySelector。若是選擇器沒有匹配到元素,將會返回 null

page.mainFrame().$(selector)的快捷方法。

page.$$(selector)

此方法在頁面上使用了 document.querySelectorAll。若是選擇器沒有匹配到元素,將會返回 []

page.mainFrame().$$(selector)的快捷方法。

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

此方法在頁面上使用了 Array.from(document.querySelectorAll(selector)),並將獲取到的結果當作 pageFunction的第一個參數傳遞進去。

若是 pageFunction返回的結果是一個 Promise,則page.$$eval將會等到前者 resolve回一個結果後,纔會繼續返回本身的值。

例子:

const divsCounts = await page.$$eval('div', divs => divs.length);
複製代碼

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

此方法在頁面上使用了 document.querySelector,並將獲取到的結果當作 pageFunction的第一個參數傳遞進去。若是選擇器沒有匹配到元素,則將拋出一個錯誤。

若是 pageFunction返回的結果是一個 Promise,則page.$eval將會等到前者 resolve回一個結果後,纔會繼續返回本身的值。

例子:

const searchValue = await page.$eval('#search', el => el.value);
const preloadHref = await page.$eval('link[rel=preload]', el => el.href);
const html = await page.$eval('.main-container', e => e.outerHTML);
複製代碼

page.mainFrame().$eval(selector, pageFunction)的快捷方法。

page.$x(expression)

根據給定的 Xpath表達式獲取 DOM元素。

page.mainFrame().$x(expression)的快捷方法。

page.addScriptTag(options)

  • options <Object>
    • url <string> 將要被添加的 script 的url.
    • path <string> 將要被添加的JavaScript文件的路徑. 若是 path 是相對路徑, 則其是相對於 current working directory
    • content <string> 將要被添加的JavaScript腳本的內容。
    • type <string> 腳本類型. 若是是 'module' ,則將導入的是JS的 ES6模塊。更多參見 script
  • returns: <Promise<ElementHandle>> 當script腳本加載完畢,或者腳本內容已經注入到頁面上時,將會返回所添加的script標籤元素。

向頁面中增長指定 url或者 腳本內容的 script標籤。

page.mainFrame().addScriptTag(options)的快捷方法。

page.addStyleTag(options)

  • options <Object>
    • url <string> 將要被添加的 style 的url
    • path <string> 將要被添加的 CSS文件的路徑. 若是 path 是相對路徑, 則其是相對於 current working directory
    • content <string> 將要被添加的CSS腳本的內容。
  • returns: <Promise<ElementHandle>>當style加載完畢,或者style內容已經注入到頁面上時,將會返回所添加的style標籤元素。

向頁面中添加一個 帶有指定 url的<link rel="stylesheet">標籤,或者一個帶有內容的<style type="text/css">標籤。

page.mainFrame().addStyleTag(options)的快捷方法。

page.authenticate(credentials)

Provide credentials for http authentication.

若是是無效的authentication,則返回 null

page.bringToFront()

Brings page to front (activates tab).

page.browser()

獲取頁面所屬的 browser實例。

page.click(selector[, options])

  • selector <string> 將要被點擊的元素的 選擇器。若是選擇器匹配出了多個元素,則點擊事件只會做用在第一個匹配的元素上。
  • options <Object>
    • button <string> left, right, or middle, 默認是 left(即便用左鍵、右鍵仍是中鍵進行點擊操做)
    • clickCount <number> 默認點擊一次。 更多參見UIEvent.detail
    • delay <number> mousedownmouseup 事件之間的時間間隔. 默認爲 0.
  • returns: <Promise> 當匹配的元素被成功點擊時將會resolve,若是沒有匹配到元素,則將 reject。

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

須要注意的是,若是所點擊的元素會觸發頁面跳轉,而且還調用了page.waitForNavigation()方法,那麼你可能不會獲得指望的結果,正確的作法以下:

const [response] = await Promise.all([
  page.waitForNavigation(waitOptions),
  page.click(selector, clickOptions),
]);
複製代碼

page.mainFrame().click(selector[, options])的快捷方法。

page.close(options)

page.close()方法默認不調用 beforeunload句柄。

(這個方法的意思是,若是頁面上註冊了 onbeforeunload方法,那麼在關閉頁面時,將會調用這個onbeforeunload方法,若是 puppeteer.launchheadless參數設置爲 true,那麼你將看到頁面在關閉時,彈出了一個詢問是否離開頁面的對話框)。

NOTE 若是runBeforeUnload 爲 true, 頁面在關閉時可能會彈出 beforeunload 對話框, 而且這個對話框能夠被 page的 'dialog'事件捕獲到.

page.content()

獲取頁面上包括 doctype在內的全部 HTML內容。

page.cookies(...urls)

若是沒有提供 URLs,則此方法將會返回當前頁面URL的 cookies。 若是指定了URLs,則只有這些指定URLS上的cookies纔會被返回。

page.coverage

page.deleteCookie(...cookies)

page.emulate(options)

  • options <Object>
    • viewport <Object>
      • width <number> page width in pixels.
      • height <number> page height in pixels.
      • deviceScaleFactor <number> Specify device scale factor (can be thought of as dpr). Defaults to 1.
      • isMobile <boolean> Whether the meta viewport tag is taken into account. Defaults to false.
      • hasTouch<boolean> Specifies if viewport supports touch events. Defaults to false
      • isLandscape <boolean> Specifies if viewport is in landscape mode. Defaults to false.
    • userAgent <string>
  • returns: <Promise>

Emulates given device metrics and user agent. This method is a shortcut for calling two methods:

puppeteer提供了一些描述設備信息的參數,這些參數能夠經過 require('puppeteer/DeviceDescriptors')命令查看。 下面是一個使用 puppeteer模擬 iPhone 6的例子。

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6'];

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.emulate(iPhone);
  await page.goto('https://www.google.com');
  // other actions...
  await browser.close();
});
複製代碼

全部可以模擬的設備能夠在DeviceDescriptors.js中找到。

page.emulateMedia(mediaType)

  • mediaType <?string> 改變頁面CSS media的類型。容許的值有 'screen', 'print' and null,若是傳入null 則表示不進行模擬。
  • returns: <Promise>

page.evaluate(pageFunction, ...args)

若是傳遞給 page.evaluatepageFunction函數返回一個 Promise,則page.evaluate將會等待獲得resolve後,纔會返回它本身的值。

若是傳遞給 page.evaluatepageFunction函數返回一個 non-Serializable的值,則page.evaluate將會返回 undefined

pageFunction傳遞參數:

const result = await page.evaluate(x => {
  return Promise.resolve(8 * x);
}, 7);
console.log(result); // prints "56"
複製代碼

能夠傳遞一個字符串做爲 pageFunction

console.log(await page.evaluate('1 + 2')); // prints "3"
const x = 10;
console.log(await page.evaluate(`1 + ${x}`)); // prints "11"
複製代碼

能夠傳遞一個ElementHandle 做爲 pageFunction參數:

const bodyHandle = await page.$('body');
const html = await page.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
複製代碼

page.mainFrame().evaluate(pageFunction, ...args)的快捷方法。

page.evaluateHandle(pageFunction, ...args)

  • pageFunction <function|string> 在page context 中執行的函數。
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction的參數
  • returns: <Promise<JSHandle>> Promise which resolves to the return value of pageFunction as in-page object (JSHandle)。

page.evaluatepage.evaluateHandle之間惟一的差異是,page.evaluateHandle返回的結果是 in-page object (JSHandle)。 (可能指的是此方法只返回頁面元素的句柄,即此方法能夠看做一個元素選擇器)

若是傳入 page.evaluateHandle的函數 返回的值是一個 Promise,則page.evaluateHandle將會等待這個 Promise到達resolve時纔會返回本身的值。

能夠傳遞一個 字符串做爲 pageFunction

const aHandle = await page.evaluateHandle('document'); // Handle for the 'document'
複製代碼

JSHandle instances也能夠做爲page.evaluateHandle的傳入參數:

const aHandle = await page.evaluateHandle(() => document.body);
const resultHandle = await page.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
複製代碼

page.mainFrame().executionContext().evaluateHandle(pageFunction, ...args)的快捷方法。

page.evaluateOnNewDocument(pageFunction, ...args)

pageFunction可能會在如下狀況下唄調用: Adds a function which would be invoked in one of the following scenarios:

  • 頁面重定向
  • 子frame重定向或者增長新的子frame。在這種狀況下,pageFunction將會在子frame中執行。

pageFunction會在文檔(document)加載完畢後以及頁面上JS腳本執行以前被調用,This is useful to amend the JavaScript environment, e.g. to seed Math.random.

下面是一個在頁面加載以前重寫 navigator.languages屬性的例子:

// preload.js

// overwrite the `languages` property to use a custom getter
Object.defineProperty(navigator, "languages", {
  get: function() {
    return ["en-US", "en", "bn"];
  }
});

// In your puppeteer script, assuming the preload.js file is in same folder of our script
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
await page.evaluateOnNewDocument(preloadFile);
複製代碼

page.exposeFunction(name, puppeteerFunction)

  • name <string> 在 window對象中添加的函數的名字
  • puppeteerFunction <function> 將會在 Puppeteer's context中執行的函數。
  • returns: <Promise>

此方法將會在 window對象中添加一個 名爲 name的函數。 當被調用時,其將會在 node.js中執行 puppeteerFunction,而且返回一個 Promise,此PromiseresolvepuppeteerFunction的返回結果。

若是puppeteerFunction返回的結果是一個 Promise,則此方法將會等到前者 Promise resolve以後,纔會返回本身的 Promise

NOTE Functions installed via page.exposeFunction survive navigations.

下面是一個在頁面中添加 md5函數的例子:

const puppeteer = require('puppeteer');
const crypto = require('crypto');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await page.exposeFunction('md5', text =>
    crypto.createHash('md5').update(text).digest('hex')
  );
  await page.evaluate(async () => {
    // use window.md5 to compute hashes
    const myString = 'PUPPETEER';
    const myHash = await window.md5(myString);
    console.log(`md5 of ${myString} is ${myHash}`);
  });
  await browser.close();
});
複製代碼

下面是一個在頁面中添加 window.readfile函數的例子:

const puppeteer = require('puppeteer');
const fs = require('fs');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('console', msg => console.log(msg.text()));
  await page.exposeFunction('readfile', async filePath => {
    return new Promise((resolve, reject) => {
      fs.readFile(filePath, 'utf8', (err, text) => {
        if (err)
          reject(err);
        else
          resolve(text);
      });
    });
  });
  await page.evaluate(async () => {
    // use window.readfile to read contents of a file
    const content = await window.readfile('/etc/hosts');
    console.log(content);
  });
  await browser.close();
});

複製代碼

page.focus(selector)

  • selector <string> 須要focus的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被focus。
  • returns: <Promise> 當成功匹配到元素後,Promise將resolve。若是沒有匹配到任何元素,則將reject。

此方法將 focus給定 selector匹配到的元素。 若是根據給定的 selector沒有匹配到任何元素,將會拋出異常。

page.mainFrame().focus(selector)的快捷方法。

page.frames()

  • returns: <Array<Frame>> 返回一個有頁面上附加的全部 frames組成的數組。

page.goBack(options)

  • options <Object> 頁面跳轉參數,包括如下屬性:
    • timeout <number> 鏈接超時時間,單位毫秒, 默認是 30秒, 若是設置爲 0則表示禁用此選項。 此值也能夠被 page.setDefaultNavigationTimeout(timeout) 方法修改。
    • waitUntil <string|Array<string>> 確認navigation成功的條件, 默認是load。若是給定的值是一個事件名稱組成的數組,那麼只有當數組中的全部事件所有被觸發後纔會認爲 navigation成功,可選的事件列表以下:
      • load - consider navigation to be finished when the load event is fired.
      • domcontentloaded - consider navigation to be finished when the DOMContentLoaded event is fired.
      • networkidle0 - 若是在 500ms內發起的http請求數爲0,則認爲導航結束。
      • networkidle2 - 若是在 500ms內發起的http請求數爲不超過 2條,則認爲導航結束。
  • returns: <Promise<?Response>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.

若是沒法 go back,則 resolve回的數據爲 null

返回上一頁。

page.goForward(options)

  • options <Object> 頁面跳轉參數,包括如下屬性:
    • timeout <number> 鏈接超時時間,單位毫秒, 默認是 30秒, 若是設置爲 0則表示禁用此選項。 此值也能夠被 page.setDefaultNavigationTimeout(timeout) 方法修改。
    • waitUntil <string|Array<string>> 確認navigation成功的條件, 默認是load。若是給定的值是一個事件組成的數組,那麼只有當數組中的全部事件所有被觸發後纔會認爲 navigation成功,可選的事件列表以下:
      • load - consider navigation to be finished when the load event is fired.
      • domcontentloaded - consider navigation to be finished when the DOMContentLoaded event is fired.
      • networkidle0 - 若是在 500ms內發起的http請求數爲0,則認爲導航結束。
      • networkidle2 - 若是在 500ms內發起的http請求數爲不超過 2條,則認爲導航結束。
  • returns: <Promise<?Response>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.

若是沒法 go forward,則 resolve回的數據爲 null

跳轉到 history裏的下一頁。

page.goto(url, options)

  • url <string> 目標頁面的url. url中應該包含協議頭,例如 https://
  • options <Object> 頁面跳轉參數,包括如下屬性:
    • timeout <number> 鏈接超時時間,單位毫秒, 默認是 30秒, 若是設置爲 0則表示禁用此選項。 此值也能夠被 page.setDefaultNavigationTimeout(timeout) 方法修改。
    • waitUntil <string|Array<string>> 確認navigation成功的條件, 默認是load。若是給定的值是一個事件組成的數組,那麼只有當數組中的全部事件所有被觸發後纔會認爲 navigation成功,可選的事件列表以下:
      • load - 當 load 事件觸發時,則認爲 navigation導航結束。
      • domcontentloaded - 當 DOMContentLoaded 事件觸發時,則認爲 navigation導航結束。
      • networkidle0 - 若是在 500ms內發起的http請求數爲0,則認爲導航結束。
      • networkidle2 - 若是在 500ms內發起的http請求數爲不超過 2條,則認爲導航結束。
  • returns: <Promise<?Response>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.

若是在頁面跳轉過程當中發生如下狀況,則此方法將拋出錯誤:

  • SSL error (例如,若是是私有證書).
  • 目標 URL失效
  • 鏈接超時
  • the main resource failed to load.

NOTE page.goto 方法要麼拋出一個錯誤,要麼返回 a main resource response,除非跳轉的連接是about:blank, 這時候,此方法將返回 null

NOTE 在 Headless mode下,此方法不支持 跳轉到 一個 PDF document。參見upstream issue.

page.hover(selector)

  • selector <string> 須要 hover的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被hover。
  • returns: <Promise> 當成功匹配到元素後,Promise將resolve。若是沒有匹配到任何元素,則將reject。

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法 hover匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

page.mainFrame().hover(selector)的快捷方法。

page.isClosed()

  • returns: boolean

頁面是否被關閉。

page.keyboard

page.mainFrame()

  • returns: <Frame> 返回頁面的 主frame。

navigations過程當中,Page一直存在一個 main frame。

page.metrics()

  • returns: <Promise<Object>> Object containing metrics as key/value pairs.
    • Timestamp <number> The timestamp when the metrics sample was taken.
    • Documents <number> Number of documents in the page.
    • Frames <number> Number of frames in the page.
    • JSEventListeners <number> Number of events in the page.
    • Nodes <number> Number of DOM nodes in the page.
    • LayoutCount <number> Total number of full or partial page layout.
    • RecalcStyleCount <number> Total number of page style recalculations.
    • LayoutDuration <number> Combined durations of all page layouts.
    • RecalcStyleDuration <number> Combined duration of all page style recalculations.
    • ScriptDuration <number> Combined duration of JavaScript execution.
    • TaskDuration <number> Combined duration of all tasks performed by the browser.
    • JSHeapUsedSize <number> Used JavaScript heap size.
    • JSHeapTotalSize <number> Total JavaScript heap size.

NOTE All timestamps are in monotonic time: monotonically increasing time in seconds since an arbitrary point in the past.

page.mouse

page.pdf(options)

  • options <Object> 具有如下屬性的參數對象:
    • path <string> 保存PDF文件的路徑. 若是path 是一個相對路徑,則它是相對於current working directory. 若是沒有提供此值項值, 將不會保存PDF。
    • scale <number> 網頁縮放的值。默認爲 1.
    • displayHeaderFooter <boolean> Display header and footer. Defaults to false.
    • headerTemplate <string> HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them:
      • date formatted print date
      • title 文檔標題
      • url 文檔url
      • pageNumber 當前頁碼
      • totalPages 總頁數
    • footerTemplate <string> HTML template for the print footer. Should use the same format as the headerTemplate.
    • printBackground <boolean> Print background graphics. Defaults to false.
    • landscape <boolean> Paper orientation. Defaults to false.
    • pageRanges <string> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
    • format <string> Paper format. If set, takes priority over width or height options. Defaults to 'Letter'.
    • width <string> Paper width, accepts values labeled with units.
    • height <string> Paper height, accepts values labeled with units.
    • margin <Object> Paper margins, defaults to none.
      • top <string> Top margin, accepts values labeled with units.
      • right <string> Right margin, accepts values labeled with units.
      • bottom <string> Bottom margin, accepts values labeled with units.
      • left <string> Left margin, accepts values labeled with units.
  • returns: <Promise<Buffer>> Promise which resolves with PDF buffer.

NOTE 生成pdf的操做只有Chrome瀏覽器纔有效。

page.pdf()print的 css media生成pdf,若是想生成一個 screenmedia的PDF,請在使用 page.pdf()以前調用page.emulateMedia('screen')方法。

// Generates a PDF with 'screen' media type.
await page.emulateMedia('screen');
await page.pdf({path: 'page.pdf'});
複製代碼

width, height, 和 margin屬性接受的值應該明確帶上相應的單位,不然將會被默認爲 px單位。

一些例子:

  • page.pdf({width: 100}) - 寬度爲100px
  • page.pdf({width: '100px'}) - 寬度爲100px
  • page.pdf({width: '10cm'}) - 寬度爲 10釐米

全部可選的單位:

  • px - pixel
  • in - inch
  • cm - centimeter
  • mm - millimeter

format 屬性的可選值:

  • Letter: 8.5in x 11in
  • Legal: 8.5in x 14in
  • Tabloid: 11in x 17in
  • Ledger: 17in x 11in
  • A0: 33.1in x 46.8in
  • A1: 23.4in x 33.1in
  • A2: 16.5in x 23.4in
  • A3: 11.7in x 16.5in
  • A4: 8.27in x 11.7in
  • A5: 5.83in x 8.27in
  • A6: 4.13in x 5.83in

NOTE headerTemplate 以及 footerTemplate的標籤有如下限制:

  1. Script tags inside templates are not evaluated.
  2. Page styles are not visible inside templates.

page.queryObjects(prototypeHandle)

  • prototypeHandle <JSHandle> A handle to the object prototype.
  • returns: <Promise<JSHandle>> Promise which resolves to a handle to an array of objects with this prototype.

此方法迭代給定的JavaScript堆的prototype,返回prototype上的全部對象

// Create a Map object
await page.evaluate(() => window.map = new Map());
// Get a handle to the Map object prototype
const mapPrototype = await page.evaluateHandle(() => Map.prototype);
// Query all map instances into an array
const mapInstances = await page.queryObjects(mapPrototype);
// Count amount of map objects in heap
const count = await page.evaluate(maps => maps.length, mapInstances);
await mapInstances.dispose();
await mapPrototype.dispose();
複製代碼

page.mainFrame().executionContext().queryObjects(prototypeHandle)的快捷方法。

page.reload(options)

  • options <Object> navigation 參數,容許具有如下屬性:
    • timeout <number> 超時時間,單位爲ms,默認爲 30s, 若是設置爲 0表示禁用此屬性。也可使用page.setDefaultNavigationTimeout(timeout) 方法來改變此值。
    • waitUntil <string|Array<string>> 確認navigation成功的條件, 默認是load。若是給定的值是一個事件組成的數組,那麼只有當數組中的全部事件所有被觸發後纔會認爲 navigation成功,可選的事件列表以下:
      • load - consider navigation to be finished when the load event is fired.
      • domcontentloaded - consider navigation to be finished when the DOMContentLoaded event is fired.
      • networkidle0 - 若是在 500ms內發起的http請求數爲0,則認爲導航結束。
      • networkidle2 - 若是在 500ms內發起的http請求數不超過 2條,則認爲導航結束。
  • returns: <Promise<Response>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.

page.screenshot([options])

  • options <Object> 此對象容許具有如下屬性:
    • path <string> 截圖保存的地址路徑。 截圖的圖片類型會自動根據文件名擴展來肯定。若是 path是相對路徑,則其應當是相對於 current working directory.。若是沒有提供此屬性值,則將不會保存截圖。
    • type <string> 指定截圖的文件類型。可選值有jpegpng。默認爲 'png'。
    • quality <number> 圖片質量, 值範圍爲 0-100。不適用於 png 圖片。
    • fullPage <boolean> 當值爲 true的話,則將截取包括可滾動區域在內的全部頁面。默認爲 false.
    • clip <Object> 用於肯定一個指定的裁剪範圍。必須具有如下屬性:
      • x <number> x-coordinate of top-left corner of clip area裁剪範圍的左上角的 x點座標
      • y <number> 裁剪範圍的左上角的 y點座標
      • width <number> 裁剪範圍的寬度
      • height <number> 裁剪範圍的高度
    • omitBackground <boolean> 隱藏默認白色背景,並容許以透明方式截取屏幕截圖。 默認爲false.
    • encoding <string> 圖片編碼方式,能夠是 base64 或者 binary。默認爲 binary.
  • returns: <Promise<[Buffer|String]>> 返回一個Promise,此Promise的resolve值是截圖的 buffer或者 base64編碼數據的字符串。

NOTE 在OS X系統上,截圖操做最少須要 1/6秒的時間。參見 crbug.com/741689

page.select(selector, ...values)

  • selector <string> [select]標籤的選擇器
  • ...values <...string> 選擇的值。若是 <select> 標籤具備 multiple 屬性, 全部的指定值都是有效值, 不然只會考慮第一個值。
  • returns: <Promise<Array<string>>> 返回一個由全部成功選中(selected)的選項(option)的值組成的數組。

當全部提供的 values值的選項(option)全被選中後會觸發 change 以及 input事件。 若是根據所指定的選擇器selector沒有匹配到一個 <select>元素,將會拋出錯誤。 (這個方法就是用於控制 select的選擇)

page.select('select#colors', 'blue'); // 單選
page.select('select#colors', 'red', 'green', 'blue'); // 多選
複製代碼

Shortcut for page.mainFrame().select()

page.setBypassCSP(enabled)

  • enabled <boolean> 設置是否繞過頁面的Content-Security-Policy(內容安全策略)。
  • returns: <Promise>

控制是否繞過頁面的Content-Security-Policy(內容安全策略)。

NOTE 繞過CSP的操做應該發生在CSP的初始化階段而不是執行階段。也就是說,在 navigating向目標主機以前就應該調用page.setBypassCSP方法。

page.setCacheEnabled(enabled)

  • enabled <boolean> sets the enabled state of the cache.
  • returns: <Promise>

是否使用資源緩存,默認啓用緩存。 Toggles ignoring cache for each request based on the enabled state. By default, caching is enabled.

page.setContent(html)

  • html <string> 設置page頁面的HTML內容。
  • returns: <Promise>

page.setCookie(...cookies)

page.setDefaultNavigationTimeout(timeout)

  • timeout <number> 導航超時時間。

此方法能夠改變如下方法默認 30s的超時時間。

page.setExtraHTTPHeaders(headers)

  • headers <Object> 一個將爲全部的請求增添額外 header屬性的對象。全部的header值必須都是 string類型。
  • returns: <Promise>

這些額外的 header頭將會被頁面發出的全部請求連接攜帶上。

NOTE page.setExtraHTTPHeaders 沒法保證請求header的順序。

page.setJavaScriptEnabled(enabled)

  • enabled <boolean> 是否啓用頁面的 JavaScript。
  • returns: <Promise>

NOTE 改變此值沒法影響到那些已經執行的 JS代碼。不過會在下次導航 navigation中徹底起做用。

page.setOfflineMode(enabled)

  • enabled <boolean> 當設置爲 true時, 將會啓用頁面的離線模式。
  • returns: <Promise>

page.setRequestInterception(value)

啓用請求攔截將會使request.abort, request.continue 以及 request.respond方法可用。這提供了可以修改頁面請求的能力。

下面的例子展現如何攔截請求並斷掉(abort)掉全部的圖片請求:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.setRequestInterception(true);
  page.on('request', interceptedRequest => {
    if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg'))
      interceptedRequest.abort();
    else
      interceptedRequest.continue();
  });
  await page.goto('https://example.com');
  await browser.close();
});
複製代碼

NOTE 啓用請求攔截將會禁用頁面緩存(也就是請求再也不使用頁面緩存)。

page.setUserAgent(userAgent)

  • userAgent <string> 指定頁面的 user agent
  • returns: <Promise> resolve頁面的 user agent

page.setViewport(viewport)

  • viewport <Object>
    • width <number> 頁面的寬度,單位爲px
    • height <number> 頁面的高度,單位爲px
    • deviceScaleFactor <number> 指定頁面縮放比例 (can be thought of as dpr). 默認爲 1.
    • isMobile <boolean> 是否考慮 meta viewport 標籤。 默認爲 false.
    • hasTouch<boolean> 設置 viewport是否支持觸摸事件。 默認爲 false
    • isLandscape <boolean> 設置 viewport是不是 landscape mode。 默認爲 false.
  • returns: <Promise>

NOTE 在某些的狀況下,設置 viewportin 將會致使頁面 reload 以便讓 isMobile 或者 hasTouch屬性生效。

若是一個瀏覽器中開啓了多個頁面,則每一個頁面都有其本身的 viewport大小。

page.tap(selector)

  • selector <string> 將要被tap的元素的 選擇器。若是選擇器匹配出了多個元素,則tap事件只會做用在第一個匹配的元素上。
  • returns: <Promise>

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.touchscreen方法tap匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

page.mainFrame().tap(selector)的快捷方法。

page.target()

  • returns: <Target> a target this page was created from.

page.title()

page.mainFrame().title()的快捷方法。

page.touchscreen

page.tracing

page.type(selector, text[, options])

  • selector <string> 文本框(包括 texarea和input)的選擇器。若是選擇器匹配出了多個元素,則只會選擇第一個匹配的元素上。
  • text <string> 將要輸入到文本框內的文字。
  • options <Object>
    • delay <number> 按鍵輸入的間隔速度,單位爲ms。默認爲 0.
  • returns: <Promise>

Sends a keydown, keypress/input, and keyup event for each character in the text.

爲了按下一些特殊按鍵,例如 ControlArrowDown,請使用keyboard.press

page.type('#mytextarea', 'Hello'); // Types instantly
page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
複製代碼

page.mainFrame().type(selector, text[, options])的快捷方法。

page.url()

page.mainFrame().url()的快捷方法。

page.viewport()

  • returns: <Object>
    • width <number> 頁面寬度,單位爲px。
    • height <number> 頁面高度,單位爲px。
    • deviceScaleFactor <number> 設備的縮放比例 (can be though of as dpr)。默認爲 1.
    • isMobile <boolean>是否考慮 meta viewport標籤。默認爲 false.
    • hasTouch<boolean> 是否支持 touch事件。默認爲 false
    • isLandscape <boolean> 設置 viewport 是否處於landscape mode。默認爲 false.

page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])

根據第一個參數的不一樣,此方法可實現的場景以下:

  • 若是 selectorOrFunctionOrTimeout是一個 string, 那麼它若是是以 '//'開頭, 就是xpath,不然就是 selector,此方法是 page.waitForSelector 或者 page.waitForXPath方法的快捷方法。
  • 若是 selectorOrFunctionOrTimeout 是一個 function, then the first argument is treated as a predicate to wait for and the method is a shortcut for page.waitForFunction().
  • 若是 selectorOrFunctionOrTimeout 是一個 number, 那麼它就會被當作是等待時間(ms),超過等到時間後將會resolve。
  • 若是不是以上三種狀況中的任何一個,那麼將會拋出錯誤。

page.mainFrame().waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])的快捷方法。

page.waitForFunction(pageFunction[, options[, ...args]])

  • pageFunction <function|string> 將要在 browser context中執行的函數(能夠是function,也能夠是string,若是是string,則是有返回值的能夠執行的 js表達式)
  • options <Object> Optional waiting parameters
    • polling <string|number> An interval at which the pageFunction is executed, defaults to raf. If polling is a number, then it is treated as an interval in milliseconds at which the function would be executed. 若是 polling 取值類型是 string, 那麼只能是如下兩個之一:
      • raf - 在 requestAnimationFrame 的回調函數中不斷地執行 pageFunction。 這是最緊湊的輪詢模式,適合於觀察樣式的變化。
      • mutation - 當任意 DOM發生變化的時候執行 pageFunction
    • timeout <number> pageFunction函數執行的最大等待時間(ms)。。默認是 30000 (30 秒)。若是取值爲 0,則表示禁用此選項。
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction的額外參數。
  • returns: <Promise<JSHandle>> 當 pageFunction函數返回 truthy value (true或者能夠轉化爲 true的值)時,將會resolve。 It resolves to a JSHandle of the truthy value.

下面是一個使用此方法來監控 viewport 尺寸改變的例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  const watchDog = page.waitForFunction('window.innerWidth < 100');
  await page.setViewport({width: 50, height: 50});
  await watchDog;
  await browser.close();
});
複製代碼

page.mainFrame().waitForFunction(pageFunction[, options[, ...args]])的快捷方法。

page.waitForNavigation(options)

  • options <Object> Navigation 參數,容許存在如下屬性:
    • timeout <number> navigation超時時間(ms),默認是 30 seconds, 取值 0則表示禁用此選項。也可使用 page.setDefaultNavigationTimeout(timeout) 方法來改變默認值。
    • waitUntil <string|Array<string>> navigation導航成功的界限, 默認是 load. 若是給定的值是一個事件名稱組成的數組,那麼只有當數組中的全部事件所有被觸發後纔會認爲 navigation成功,可選的事件列表以下:
      • load - 當 load 事件觸發時,則認爲 navigation導航結束。
      • domcontentloaded - 當 DOMContentLoaded 事件觸發時,則認爲 navigation導航結束。
      • networkidle0 - 若是在 500ms內發起的http請求數爲0,則認爲導航結束。
      • networkidle2 - 若是在 500ms內發起的http請求數爲不超過 2條,則認爲導航結束。
  • returns: <Promise<Response>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.

適應於當頁面重定向到一個新的url或者reload的場景,例如,當執行了一段可能間接致使頁面跳轉的代碼:

const navigationPromise = page.waitForNavigation();
await page.click('a.my-link'); // 點擊此連接將會間接致使頁面跳轉
await navigationPromise; // 當頁面跳轉完畢後,將會 resolve
複製代碼

NOTE 使用 History API 方法改變 URL也會被當成是一個 navigation。

page.waitForSelector(selector[, options])

  • selector <string> 被等待的元素的選擇器selector
  • options <Object> 可選參數:
    • visible <boolean> 出如今DOM中的元素必須是可見的(visible),例如,不能有 display: none 或者 visibility: hidden CSS 屬性。默認是 false
    • hidden <boolean> 元素不存在於DOM中(包括一開始就不存在,或者存在了又被移除掉),或者是被隱藏了, 例如, 具備 display: none 或者 visibility: hidden CSS 屬性。默認是 false.
    • timeout <number> 最大等待時間(ms)。默認是 30000 (30 秒)。取值爲的 0則表示禁用此參數。
  • returns: <Promise<ElementHandle>> 當在 DOM中找到 selector指定的元素時,Promise 將會 resolves 這個元素的ElementHandle。

等到 selector選擇器選擇的元素出如今頁面中,若是在調用此方法的同時選擇器選取的元素就已經存在於頁面中了, 則此方法將會當即返回結果,若是超過了最大等待時間 timeout以後,選擇器尚未匹配到元素,則將會拋出錯誤。

此方法即使是在頁面跳轉(across navigations)的時候依舊有效:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  let currentURL;
  page
    .waitForSelector('img')
    .then(() => console.log('First URL with image: ' + currentURL));
  for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com'])
    await page.goto(currentURL);
  await browser.close();
});
複製代碼

page.mainFrame().waitForSelector(selector[, options])的快捷方法。

page.waitForXPath(xpath[, options])

  • xpath <string> 匹配xpath的元素
  • options <Object> 可選參數以下:
    • visible <boolean> 出如今DOM中的元素必須是可見的(visible),例如,不能有 display: none 或者 visibility: hidden CSS 屬性。默認是 false
    • hidden <boolean> 元素不存在於DOM中(包括一開始就不存在,或者存在了又被移除掉),或者是被隱藏了, 例如, 具備 display: none 或者 visibility: hidden CSS 屬性。默認是 false.
    • timeout <number> 最大等待時間(ms)。默認是 30000 (30 秒)。取值爲的 0則表示禁用此參數。
  • returns: <Promise<ElementHandle>> 當在 DOM中找到匹配 xpath的元素時,Promise 將會 resolves 這個元素的ElementHandle。

等到匹配 xpath的元素出如今頁面中,若是在調用此方法的同時匹配 xpath的元素就已經存在於頁面中了, 則此方法將會當即返回結果,若是超過了最大等待時間 timeout以後,尚未出現匹配 xpath的元素,則將會拋出錯誤。

此方法即使是在頁面跳轉(across navigations)的時候依舊有效:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  let currentURL;
  page
    .waitForXPath('//img')
    .then(() => console.log('First URL with image: ' + currentURL));
  for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com'])
    await page.goto(currentURL);
  await browser.close();
});
複製代碼

page.mainFrame().waitForXPath(xpath[, options])的快捷方法。

page.workers()

NOTE 不包括 ServiceWorkers。

class: Worker

The Worker class represents a WebWorker. workercreatedworkerdestroyed事件將會被當作 worker的生命週期,在 page實例中被觸發。

page.on('workercreated', worker => console.log('Worker created: ' + worker.url()));
page.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url()));

console.log('Current workers:');
for (const worker of page.workers())
  console.log(' ' + worker.url());
複製代碼

worker.evaluate(pageFunction, ...args)

若是pageFunction返回的值是一個 Promise,則 worker.evaluate方法將會等到前者 resolve後,纔會返回它本身的值。

若是pageFunction返回的值是一個 non-Serializable 的值, 則 worker.evaluate 將會 resolves undefined

(await worker.executionContext()).evaluate(pageFunction, ...args)的快捷方法。

worker.evaluateHandle(pageFunction, ...args)

  • pageFunction <function|string> 將在page context中執行的函數。
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction函數的參數。
  • returns: <Promise<JSHandle>> Promise which resolves to the return value of pageFunction as in-page object (JSHandle)

worker.evaluateworker.evaluateHandle之間惟一的區別在於,worker.evaluateHandle返回一個 in-page object (JSHandle)

若是pageFunction返回的值是一個 Promise,則 worker.evaluateHandle方法將會等到前者 resolve後,纔會返回它本身的值。

(await worker.executionContext()).evaluateHandle(pageFunction, ...args)的快捷方法。

worker.executionContext()

worker.url()

class: Keyboard

Keyboard提供了一些用於操縱虛擬鍵盤的api。高級api是keyboard.type,此api可自動根據場景整合keydown, keypress/input, 以及 keyup事件。

爲了獲得更細緻的控制,你也可使用keyboard.down, keyboard.up, and keyboard.sendCharacter方法來觸發相應的鍵盤事件,以此達到模擬真實體驗的目的。

下面是一個按住 Shift鍵,而後選中並刪除一些文本的例子:

await page.keyboard.type('Hello World!');
await page.keyboard.press('ArrowLeft');

await page.keyboard.down('Shift');
for (let i = 0; i < ' World'.length; i++)
  await page.keyboard.press('ArrowLeft');
await page.keyboard.up('Shift');

await page.keyboard.press('Backspace');
// 最終獲得的文本將是 'Hello!'
複製代碼

下面是一個輸入 'A 字母的例子:

await page.keyboard.down('Shift');
await page.keyboard.press('KeyA');
await page.keyboard.up('Shift');
複製代碼

NOTE 在MacOS系統上,一些鍵盤快捷鍵,例如 全選 的快捷鍵⌘ A將不起做用。更多參見 #1313

keyboard.down(key[, options])

  • key <string> 按下的按鍵名稱, such as ArrowLeft. 參見 USKeyboardLayout 獲取按鍵名稱列表。
  • options <Object>
    • text <string> 若是指定了此屬性值, generates an input event with this text.
  • returns: <Promise>

觸發 keydown事件。

若是 key值是一個單個字母,而且沒有除了 Shift以外的修飾按鍵被按下,那麼將會繼續觸發 keypress/input事件。能夠指定 'text'選項以強制生成輸入事件。

若是 key值是一個修飾按鍵,例如 Shift, Meta, Control, 或者 Alt,隨後按下的按鍵將會與前者組合造成組合鍵,若是想要釋放修飾按鍵,可使用 keyboard.up方法。

After the key is pressed once, subsequent calls to keyboard.down will have repeat set to true. To release the key, use keyboard.up.

NOTE 修飾鍵將會影響 keyboard.down的效果。若是你按住 Shift鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。

keyboard.press(key[, options])

  • key <string> 須要按下的按鍵的名稱, 例如 ArrowLeft. 更多按鍵名稱列表參見 USKeyboardLayout
  • options <Object>
    • text <string> 若是指定,則將根據 text進行按鍵操做。
    • delay <number> keydownkeyup 之間的時間間隔(ms). 默認是 0.
  • returns: <Promise>

若是 key值是一個單個字母,而且沒有除了 Shift以外的修飾按鍵被按下,那麼將會繼續觸發 keypress/input事件。能夠指定 'text'選項以強制生成輸入事件。

NOTE 修飾鍵將會影響 keyboard.press的效果。若是你按住 Shift鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。

keyboard.downkeyboard.up的快捷方法。

keyboard.sendCharacter(char)

觸發 keypressinput事件,不會觸發 keydown 或者 keyup 事件。

page.keyboard.sendCharacter('嗨');1
複製代碼

NOTE 修飾鍵將會影響 keyboard.sendCharacter的效果。若是你按住 Shift鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。

keyboard.type(text, options)

  • text <string> 須要向聚焦的輸入框中輸入的文本
  • options <Object>
    • delay <number> 按鍵按下的時間間隔. 默認是 0.
  • returns: <Promise>

輸入文本的時候,每一個字符都會觸發 keydown, keypress/input, 以及 keyup事件。

若是想要輸按下特殊字符,例如Control 以及 ArrowDown,參見keyboard.press

page.keyboard.type('Hello'); // 快速輸入
page.keyboard.type('World', {delay: 100}); // 模擬真實輸入
複製代碼

NOTE 修飾鍵不會影響 keyboard.type的效果。也就是說,調用此方法時,就算你已經按住了 Shift鍵,也不會將你想要輸入的文本全都強制變成大寫的。

keyboard.up(key)

觸發 keyup事件。

class: Mouse

mouse.click(x, y, [options])

  • x <number>
  • y <number>
  • options <Object>
    • button <string> left, right, 或者 middle, 默認是 left。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)
    • clickCount <number> 點擊次數,默認是 1. 參見 UIEvent.detail.
    • delay <number> mousedownmouseup 之間的時間間隔(ms).默認是 0.
  • returns: <Promise>

mouse.move, mouse.down 以及 mouse.up的聯合方法。

mouse.down([options])

  • options <Object>
    • button <string> left, right, 或者 middle, 默認是 left。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)
    • clickCount <number>默認是 1. 參見 UIEvent.detail.
  • returns: <Promise>

觸發 mousedown事件。

mouse.move(x, y, [options])

觸發 mousemove事件。

mouse.up([options])

觸發 mouseup事件。

class: Touchscreen

touchscreen.tap(x, y)

Dispatches a touchstart and touchend event.

class: Tracing

你可使用 tracing.start 以及 tracing.stop來建立一個跟蹤文件,此跟蹤文件能夠被 Chrome DevTools 或者 timeline viewer打開。

await page.tracing.start({path: 'trace.json'});
await page.goto('https://www.google.com');
await page.tracing.stop();
複製代碼

tracing.start(options)

  • options <Object>
    • path <string> 跟蹤文件的存儲路徑.
    • screenshots <boolean> captures screenshots in the trace.
    • categories <Array<string>> specify custom categories to use instead of default.
  • returns: <Promise>

每一個瀏覽器一次只能執行一個跟蹤任務。

tracing.stop()

  • returns: <Promise<Buffer>> Promise which resolves to buffer with trace data.

class: Dialog

Dialog objects are dispatched by page via the 'dialog' event.

下面是一個 使用Dialog class的例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('dialog', async dialog => {
    console.log(dialog.message());
    await dialog.dismiss();
    await browser.close();
  });
  page.evaluate(() => alert('1'));
});
複製代碼

dialog.accept([promptText])

  • promptText <string> 在提示框中輸入的文件內容。。若是dialog的類型不是prompt(提示框),則此方法將不起任何做用。
  • returns: <Promise> Promise which resolves when the dialog has been accepted.

dialog.defaultValue()

  • returns: <string> 若是 dialog是一個 prompt(提示框),返回提示框的默認值,不然將返回空字符串。

dialog.dismiss()

  • returns: <Promise> 提示框被取消時,Promise 返回resolves 。

dialog.message()

  • returns: <string> dialog展現的文本。

dialog.type()

  • returns: <string> Dialog的類型, 能夠是如下其中之一 alert, beforeunload, confirm or prompt.

class: ConsoleMessage

ConsoleMessage objects are dispatched by page via the 'console' event.

consoleMessage.args()

consoleMessage.text()

consoleMessage.type()

容許如下值: 'log', 'debug', 'info', 'error', 'warning', 'dir', 'dirxml', 'table', 'trace', 'clear', 'startGroup', 'startGroupCollapsed', 'endGroup', 'assert', 'profile', 'profileEnd', 'count', 'timeEnd'

class: Frame

不管在哪一個時間點,都可以經過page.mainFrame()frame.childFrames()方法來獲取的頁面當前的 frame tree。

Frame對象的生命週期,由三個事件組成:

  • 'frameattached' - 當frame attach到page上時觸發。一個 Frame只能 attach到頁面上一次。
  • 'framenavigated' - 當Frame重定向到一個新的 URL時觸發.
  • 'framedetached' - 當Frame從頁面上 detach時觸發。一個 Frame只能從頁面上 detach一次。

An example of dumping frame tree:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://www.google.com/chrome/browser/canary.html');
  dumpFrameTree(page.mainFrame(), '');
  await browser.close();

  function dumpFrameTree(frame, indent) {
    console.log(indent + frame.url());
    for (let child of frame.childFrames())
      dumpFrameTree(child, indent + ' ');
  }
});
複製代碼

frame.$(selector)

  • selector <string> Selector to query page for
  • returns: <Promise<?ElementHandle>> Promise which resolves to ElementHandle pointing to the frame element.

在 frame上搜索元素。若是沒有找到所需匹配的元素,則resolve會 null

frame.$$(selector)

  • selector <string> Selector to query page for
  • returns: <Promise<Array<ElementHandle>>> Promise which resolves to ElementHandles pointing to the frame elements.

此方法使用了 document.querySelectorAll,若是沒有匹配到任何元素,則resolve回 []

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

此方法使用了 Array.from(document.querySelectorAll(selector)),並將其返回的結果做爲 pageFunction函數的第一個參數傳遞進去。

若是 pageFunction返回的結果是一個 Promise,則 frame.$$eval將會等到前者成功resolve,而後再返回本身的值。

Examples:

const divsCounts = await frame.$$eval('div', divs => divs.length);
複製代碼

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

此方法使用了 document.querySelector,並將其返回的結果做爲 pageFunction函數的第一個參數傳遞進去。若是沒有匹配到任何元素,則將拋出錯誤。

若是 pageFunction返回的結果是一個 Promise,則 frame.$eval將會等到前者成功resolve,而後再返回本身的值。

例子:

const searchValue = await frame.$eval('#search', el => el.value);
const preloadHref = await frame.$eval('link[rel=preload]', el => el.href);
const html = await frame.$eval('.main-container', e => e.outerHTML);
複製代碼

frame.$x(expression)

此方法用於執行給定的 XPath 表達式。

frame.addScriptTag(options)

  • options <Object>
    • url <string> 須要被增長的script標籤的url
    • path <string> 將要被添加的JavaScript文件的路徑. 若是 path 是相對路徑, 則其是相對於 current working directory
    • content <string> 將要被添加的 JavaScript腳本的內容。
    • type <string> 腳本類型. 若是是 'module' ,則將導入的是JS的 ES6模塊。更多參見 [script]
  • returns: <Promise<ElementHandle>> 當script腳本加載完畢,或者腳本內容已經注入到frame上時,將會返回所添加的script標籤元素。

向frame中增長指定 url或者 腳本內容的 script標籤。

frame.addStyleTag(options)

  • options <Object>
    • url <string> 將要被添加的 style 的url
    • path <string>將要被添加的 CSS文件的路徑. 若是 path 是相對路徑, 則其是相對於 current working directory
    • content <string> 將要被添加的CSS腳本的內容。
  • returns: <Promise<ElementHandle>> 當style加載完畢,或者style內容已經注入到frame上時,將會返回所添加的style標籤元素。

向頁面中添加一個 帶有指定 url的<link rel="stylesheet">標籤,或者一個帶有內容的<style type="text/css">標籤。

frame.childFrames()

frame.click(selector[, options])

  • selector <string> 將要被點擊的元素的 選擇器。若是選擇器匹配出了多個元素,則點擊事件只會做用在第一個匹配的元素上。
  • options <Object>
    • button <string> left, right, or middle, 默認是 left(即便用左鍵、右鍵仍是中鍵進行點擊操做)
    • clickCount <number> 默認點擊一次。 更多參見UIEvent.detail
    • delay <number> mousedownmouseup 事件之間的時間間隔. 默認爲 0.
  • returns: <Promise> 當匹配的元素被成功點擊時將會resolve,若是沒有匹配到元素,則將 reject。

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

須要注意的是,若是所點擊的元素會觸發頁面跳轉,而且還調用了page.waitForNavigation()方法,那麼你可能不會獲得指望的結果,正確的作法以下:

const [response] = await Promise.all([
  page.waitForNavigation(waitOptions),
  frame.click(selector, clickOptions),
]);
複製代碼

frame.content()

獲取frame包括doctype在內的完整HTML內容

frame.evaluate(pageFunction, ...args)

若是傳遞給 frame.evaluatepageFunction函數返回一個 Promise,則frame.evaluate將會等待獲得resolve後,纔會返回它本身的值。

若是傳遞給 frame.evaluatepageFunction函數返回一個 non-Serializable的值,則page.evaluate將會返回 undefined

const result = await frame.evaluate(() => {
  return Promise.resolve(8 * 7);
});
console.log(result); // prints "56"
複製代碼

能夠傳遞一個字符串做爲 pageFunction

console.log(await frame.evaluate('1 + 2')); // prints "3"
複製代碼

能夠傳遞一個ElementHandle 做爲 pageFunction參數:

const bodyHandle = await frame.$('body');
const html = await frame.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
複製代碼

frame.evaluateHandle(pageFunction, ...args)

  • pageFunction <function|string> 在page context 中執行的函數。
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction的參數
  • returns: <Promise<JSHandle>> Promise which resolves to the return value of pageFunction as in-page object (JSHandle)

frame.evaluatepaframege.evaluateHandle之間惟一的差異是,frame.evaluateHandle返回的結果是 in-page object (JSHandle)。 (可能指的是此方法只返回頁面元素的句柄,即此方法能夠看做一個元素選擇器)

若是傳入 frame.evaluateHandle的函數 返回的值是一個 Promise,則frame.evaluateHandle將會等待這個 Promise到達resolve時纔會返回本身的值。

const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window));
aWindowHandle; // window對象的handle.
複製代碼

能夠傳遞一個 字符串做爲 pageFunction

const aHandle = await frame.evaluateHandle('document'); // Handle for the 'document'.
複製代碼

JSHandle instances也能夠做爲frame.evaluateHandle的傳入參數:

const aHandle = await frame.evaluateHandle(() => document.body);
const resultHandle = await frame.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
複製代碼

frame.executionContext()

frame.focus(selector)

  • selector <string> 須要focus的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被focus。
  • returns: <Promise> 當成功匹配到元素後,Promise將resolve。若是沒有匹配到任何元素,則將reject。

此方法將 focus給定 selector匹配到的元素。 若是根據給定的 selector沒有匹配到任何元素,將會拋出異常。

frame.hover(selector)

  • selector <string> 須要 hover的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被hover。
  • returns: <Promise> 當成功匹配到元素後,Promise將resolve。若是沒有匹配到任何元素,則將reject。

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法 hover匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

frame.isDetached()

若是 frame已經detached了,則返回 true, 不然返回 false

frame.name()

返回 frame的name屬性值。

若是name屬性不存在或者爲空字符串,則返回 id屬性的值,若是 id屬性也不存在或者爲空字符串,則返回空字符串。

NOTE 此方法的返回值只會在frame被建立後計算一次,若是稍後frame的相關屬性(name或者id)發生變化,此方法的返回值也不會改變。

frame.parentFrame()

  • returns: <?Frame> 若是存在父級 frame,則返回父級 frame, 對已經 detach的frame或者 main frame使用此方法將會返回 null

frame.select(selector, ...values)

  • selector <string> [select]標籤的選擇器
  • ...values <...string> 選擇的值。若是 <select> 標籤具備 multiple 屬性, 全部的指定值都是有效值, 不然只會考慮第一個值。
  • returns: <Promise<Array<string>>> 返回一個由全部成功選中(selected)的選項(option)的值組成的數組。

當全部提供的 values值的選項(option)全被選中後會觸發 change 以及 input事件。 若是根據所指定的選擇器selector沒有匹配到一個 <select>元素,將會拋出錯誤。 (這個方法就是用於控制 select的選擇)

frame.select('select#colors', 'blue'); // 單選
frame.select('select#colors', 'red', 'green', 'blue'); // 多選
複製代碼

frame.setContent(html)

  • html <string> 設置 page頁面的HTML內容。
  • returns: <Promise>

frame.tap(selector)

  • selector <string> 將要被tap的元素的 選擇器。若是選擇器匹配出了多個元素,則tap事件只會做用在第一個匹配的元素上。
  • returns: <Promise>

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.touchscreen方法tap匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。

frame.title()

frame.type(selector, text[, options])

  • selector <string> 文本框(包括 texarea和input)的選擇器。若是選擇器匹配出了多個元素,則只會選擇第一個匹配的元素上。
  • text <string> 將要輸入到文本框內的文字。
  • options <Object>
    • delay <number> 按鍵輸入的間隔速度,單位爲ms。默認爲 0.
  • returns: <Promise>

Sends a keydown, keypress/input, and keyup event for each character in the text.

爲了按下一些特殊按鍵,例如 ControlArrowDown,請使用keyboard.press

frame.type('#mytextarea', 'Hello'); // 快速輸入
frame.type('#mytextarea', 'World', {delay: 100}); // 減緩輸入速度以模擬真實輸入
複製代碼

frame.url()

返回 frame的url

frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])

根據第一個參數的不一樣,此方法可實現的場景以下:

  • 若是 selectorOrFunctionOrTimeout是一個 string, 那麼它若是是以 '//'開頭, 就是xpath,不然就是 selector,此方法是 frame.waitForSelector 或者 frame.waitForXPath方法的快捷方法。
  • 若是 selectorOrFunctionOrTimeout 是一個 function, then the first argument is treated as a predicate to wait for and the method is a shortcut for frame.waitForFunction().
  • 若是 selectorOrFunctionOrTimeout 是一個 number, 那麼它就會被當作是等待時間(ms),超過等到時間後將會resolve。
  • 若是不是以上三種狀況中的任何一個,那麼將會拋出錯誤。

frame.waitForFunction(pageFunction[, options[, ...args]])

  • pageFunction <function|string> 將要在 browser context中執行的函數(能夠是function,也能夠是string,若是是string,則是有返回值的能夠執行的 js表達式)
  • options <Object> Optional waiting parameters
    • polling <string|number> An interval at which the pageFunction is executed, defaults to raf. If polling is a number, then it is treated as an interval in milliseconds at which the function would be executed. 若是 polling 取值類型是 string, 那麼只能是如下兩個之一:
      • raf - 在 requestAnimationFrame 的回調函數中不斷地執行 pageFunction。 這是最緊湊的輪詢模式,適合於觀察樣式的變化。
      • mutation - 當任意 DOM發生變化的時候執行
    • timeout <number> 函數執行的最大等待時間(ms)。。默認是 30000 (30 秒)。若是取值爲 0,則表示禁用此選項。
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction的額外參數。
  • returns: <Promise<JSHandle>> Promise which resolves when the pageFunction returns a truthy value. It resolves to a JSHandle of the truthy value.

下面是一個使用此方法來監控 viewport 尺寸改變的例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  const watchDog = page.mainFrame().waitForFunction('window.innerWidth < 100');
  page.setViewport({width: 50, height: 50});
  await watchDog;
  await browser.close();
});
複製代碼

frame.waitForSelector(selector[, options])

  • selector <string> 被等待的元素的選擇器selector
  • options <Object> 可選參數
    • visible <boolean> 出如今DOM中的元素必須是可見的(visible),例如,不能有 display: none 或者 visibility: hidden CSS 屬性。默認是 false
    • hidden <boolean> 元素不存在於DOM中(包括一開始就不存在,或者存在了又被移除掉),或者是被隱藏了, 例如, 具備 display: none 或者 visibility: hidden CSS 屬性。默認是 false.
    • timeout <number> 最大等待時間(ms)。默認是 30000 (30 秒)。取值爲的 0則表示禁用此參數。
  • returns: <Promise<ElementHandle>> 當在 DOM中找到 selector指定的元素時,Promise 將會 resolves 這個元素的ElementHandle。

等到 selector選擇器選擇的元素出如今頁面中,若是在調用此方法的同時選擇器選取的元素就已經存在於頁面中了, 則此方法將會當即返回結果,若是超過了最大等待時間 timeout以後,選擇器尚未匹配到元素,則將會拋出錯誤。

此方法即使是在頁面跳轉(across navigations)的時候依舊有效:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  let currentURL;
  page.mainFrame()
    .waitForSelector('img')
    .then(() => console.log('First URL with image: ' + currentURL));
  for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com'])
    await page.goto(currentURL);
  await browser.close();
});
複製代碼

frame.waitForXPath(xpath[, options])

  • xpath <string> 匹配xpath的元素
  • options <Object> 可選參數以下:
    • visible <boolean> 出如今DOM中的元素必須是可見的(visible),例如,不能有 display: none 或者 visibility: hidden CSS 屬性。默認是 false
    • hidden <boolean> 元素不存在於DOM中(包括一開始就不存在,或者存在了又被移除掉),或者是被隱藏了, 例如, 具備 display: none 或者 visibility: hidden CSS 屬性。默認是 false.
    • timeout <number> 最大等待時間(ms)。默認是 30000 (30 秒)。取值爲的 0則表示禁用此參數。
  • returns: <Promise<ElementHandle>> 當在 DOM中找到匹配 xpath的元素時,Promise 將會 resolves 這個元素的ElementHandle。

等到匹配 xpath的元素出如今頁面中,若是在調用此方法的同時匹配 xpath的元素就已經存在於頁面中了, 則此方法將會當即返回結果,若是超過了最大等待時間 timeout以後,尚未出現匹配 xpath的元素,則將會拋出錯誤。

此方法即使是在頁面跳轉(across navigations)的時候依舊有效:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  let currentURL;
  page.mainFrame()
    .waitForXPath('//img')
    .then(() => console.log('First URL with image: ' + currentURL));
  for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com'])
    await page.goto(currentURL);
  await browser.close();
});
複製代碼

class: ExecutionContext

The class represents a context for JavaScript execution. Examples of JavaScript contexts are:

  • 每一個 frame 都有一個獨立的JS執行上下文
  • 全部類型的 workers 都有它們本身的上下文

executionContext.evaluate(pageFunction, ...args)

若是pageFunction函數的返回值是一個 Promise,則executionContext.evaluate將會等到前者resolve後纔會返回它本身的值。

const executionContext = await page.mainFrame().executionContext();
const result = await executionContext.evaluate(() => Promise.resolve(8 * 7));
console.log(result); // prints "56"
複製代碼

字符串也能夠被當作pageFunction

console.log(await executionContext.evaluate('1 + 2')); // prints "3"
複製代碼

JSHandle instances 能夠被當作 ...args

const oneHandle = await executionContext.evaluateHandle(() => 1);
const twoHandle = await executionContext.evaluateHandle(() => 2);
const result = await executionContext.evaluate((a, b) => a + b, oneHandle, twoHandle);
await oneHandle.dispose();
await twoHandle.dispose();
console.log(result); // prints '3'.
複製代碼

executionContext.evaluateHandle(pageFunction, ...args)

  • pageFunction <function|string> 將在executionContext中執行的函數
  • ...args <...Serializable|JSHandle> 傳遞給 pageFunction函數的參數。
  • returns: <Promise<JSHandle>> Promise which resolves to the return value of pageFunction as in-page object (JSHandle)

executionContext.evaluateexecutionContext.evaluateHandle之間惟一的區別在於,worker.evaluateHandle返回一個 in-page object (JSHandle)

若是pageFunction返回的值是一個 Promise,則 executionContext.evaluateHandle方法將會等到前者 resolve後,纔會返回它本身的值。

const context = await page.mainFrame().executionContext();
const aHandle = await context.evaluateHandle(() => Promise.resolve(self));
aHandle; // Handle for the global object.
複製代碼

字符串也能夠被當作pageFunction

const aHandle = await context.evaluateHandle('1 + 2'); // Handle for the '3' object.
複製代碼

JSHandle instances 能夠被當作 ...args

const aHandle = await context.evaluateHandle(() => document.body);
const resultHandle = await context.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue()); // prints body's innerHTML
await aHandle.dispose();
await resultHandle.dispose();
複製代碼

executionContext.frame()

  • returns: <?Frame> Frame associated with this execution context.

NOTE 並非每個 execution context都存在一個frame。例如, workers 以及 extensions 都存在 execution context,可是沒有 frame。

executionContext.queryObjects(prototypeHandle)

  • prototypeHandle <JSHandle> A handle to the object prototype.
  • returns: <JSHandle> A handle to an array of objects with this prototype

此方法迭代(iterates)遍歷 JavaScript堆棧,獲取給定 prototype下全部 object組成的數組。

// Create a Map object
await page.evaluate(() => window.map = new Map());
// Get a handle to the Map object prototype
const mapPrototype = await page.evaluateHandle(() => Map.prototype);
// Query all map instances into an array
const mapInstances = await page.queryObjects(mapPrototype);
// Count amount of map objects in heap
const count = await page.evaluate(maps => maps.length, mapInstances);
await mapInstances.dispose();
await mapPrototype.dispose();
複製代碼

class: JSHandle

JSHandle represents an in-page JavaScript object. JSHandles 能夠經過 page.evaluateHandle 方法來建立。

const windowHandle = await page.evaluateHandle(() => window);
// ...
複製代碼

JSHandle可以防止被引用的 JavaScript object 被垃圾回收機制給回收掉,除非 the handle被主動 disposed。JSHandles可以在源frame重定向或者父級上下文被銷燬的時候,自動釋放(auto-disposed)。

JSHandle instances 能夠做爲 page.$eval(), page.evaluate() 以及 page.evaluateHandle 方法的參數。

jsHandle.asElement()

若是當前 object handle是ElementHandle的實例,則將返回object handle自己,不然返回 null

jsHandle.dispose()

  • returns: <Promise> 當 object handle成功釋放(dispose)後,Promise將 resolve。

此方法用於斷開element handle的引用

jsHandle.executionContext()

返回 handle所在的執行上下文。

jsHandle.getProperties()

此方法返回一個由屬性名稱做爲key和 JSHandle instances做爲value組成的 map對象

const handle = await page.evaluateHandle(() => ({window, document}));
const properties = await handle.getProperties();
const windowHandle = properties.get('window');
const documentHandle = properties.get('document');
await handle.dispose();
複製代碼

jsHandle.getProperty(propertyName)

從引用的object中獲取給定 propertyName對應的 property。

jsHandle.jsonValue()

返回 object的 json。若是 object具備toJSON函數方法,也不會調用此函數方法. Returns a JSON representation of the object. If the object has a

NOTE 若是引用的object沒法字符串化,則此方法將返回空 JSON對象。若是引用的object存在循環引用,則將拋出錯誤。

class: ElementHandle

NOTE Class ElementHandle extends JSHandle.

ElementHandle represents an in-page DOM element. ElementHandles 能夠經過 the page.$ 方法建立。

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  await page.goto('https://google.com');
  const inputElement = await page.$('input[type=submit]');
  await inputElement.click();
  // ...
});
複製代碼

ElementHandle 可以防止被引用的 DOM element 被垃圾回收機制給回收掉,除非 the handle被主動 disposed。ElementHandles 可以在源frame重定向的時候,自動釋放(auto-disposed)。

ElementHandle instances 能夠做爲 page.$eval(), page.evaluate() 以及 page.evaluate 方法的參數。

elementHandle.$(selector)

此方法將在頁面上使用element.querySelector,若是沒有匹配到任何元素,則將resolve 回null

elementHandle.$$(selector)

此方法將在頁面上使用element.querySelectorAll,若是沒有匹配到任何元素,則將resolve 回[]

elementHandle.$$eval(selector, pageFunction, ...args)

此方法將在element上使用element.querySelectorAll,而且將結果做爲pageFunction的第一個參數傳入,若是沒有匹配到任何元素,則拋出錯誤。

若是 pageFunction返回的值是一個 Promise,則 elementHandle.$$eval將等到前者 resolve回結果後,才返回它本身的值。

例子:

<div class="feed">
  <div class="tweet">Hello!</div>
  <div class="tweet">Hi!</div>
</div>
複製代碼
const feedHandle = await page.$('.feed');
expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText)).toEqual(['Hello!', 'Hi!']);
複製代碼

elementHandle.$eval(selector, pageFunction, ...args)

此方法將在 element上使用document.querySelector,而且將結果做爲pageFunction的第一個參數傳入,若是沒有匹配到任何元素,則拋出錯誤。

若是 pageFunction返回的值是一個 Promise,則 elementHandle.$eval將等到前者 resolve回結果後,才返回它本身的值。

Examples:

const tweetHandle = await page.$('.tweet');
expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100');
expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10');
複製代碼

elementHandle.$x(expression)

The method evaluates the XPath expression relative to the elementHandle. If there are no such elements, the method will resolve to an empty array.

elementHandle.asElement()

elementHandle.boundingBox()

  • returns: <Promise<?Object>>
    • x <number> element 的 x座標, 單位是px.
    • y <number> element 的 y座標, 單位是px.
    • width <number> element 的寬度, 單位是px.
    • height <number> element 的高度, 單位是px.

此方法返回 element 的 bounding box(即座標和長、寬信息,座標是相對於main frame的),若是element不可見(not visible),則返回 null

elementHandle.boxModel()

  • returns: <Promise<?Object>>
    • content <Array<Object>> Content box, represented as an array of {x, y} points.
    • padding <Array<Object>> Padding box, represented as an array of {x, y} points.
    • border <Array<Object>> Border box, represented as an array of {x, y} points.
    • margin <Array<Object>> Margin box, represented as an array of {x, y} points.
    • width <number> Element's width.
    • height <number> Element's height.

此方法返回element的盒模型信息,若是element不可見(not visible),則返回 null Boxes are represented as an array of points; each Point is an object {x, y}. Box points are sorted clock-wise.

elementHandle.click([options])

  • options <Object>
    • button <string> left, right, 或者 middle, 默認是 left。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)
    • clickCount <number> 點擊次數,默認是 1. 參見 UIEvent.detail.
    • delay <number> mousedownmouseup 之間的時間間隔(ms).默認是 0.
  • returns: <Promise> Promise which resolves when the element is successfully clicked. Promise gets rejected if the element is detached from DOM.

此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是element 已經從DOM上 detach掉了,則將拋出一個錯誤。

elementHandle.contentFrame()

  • returns: <Promise<?Frame>> Resolves to the content frame for element handles referencing iframe nodes, or null otherwise

elementHandle.dispose()

  • returns: <Promise> Promise which resolves when the element handle is successfully disposed.

此方法斷開 element handle的引用

elementHandle.executionContext()

elementHandle.focus()

調用 element的focus 方法。

elementHandle.getProperties()

此方法返回一個由屬性名稱做爲key和 JSHandle instances做爲value組成的 map對象

const listHandle = await page.evaluateHandle(() => document.body.children);
const properties = await listHandle.getProperties();
const children = [];
for (const property of properties.values()) {
  const element = property.asElement();
  if (element)
    children.push(element);
}
children; // holds elementHandles to all children of document.body
複製代碼

elementHandle.press(key[, options])

  • key <string> 須要按下的按鍵的名稱, 例如 ArrowLeft. 更多按鍵名稱列表參見 USKeyboardLayout
  • options <Object>
    • text <string> If specified, generates an input event with this text.
    • delay <number> keydownkeyup 之間的時間間隔(ms). 默認是 0.
  • returns: <Promise>

聚焦在 element上,而後使用 keyboard.down 以及 keyboard.up方法。

若是 key值是一個單個字母,而且沒有除了 Shift以外的修飾按鍵被按下,那麼將會繼續觸發 keypress/input事件。能夠指定 'text'選項以強制生成輸入事件。

NOTE 修飾鍵將會影響 elementHandle.press的效果。若是你按住 Shift鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。

elementHandle.screenshot([options])

此方法將會在須要的時候將元素滾動到可視區域內,而後使用 page.screenshot方法來對 element進行截圖操做。 若是 element 已經從DOM上 detach掉了,則此方法將拋出錯誤。

elementHandle.tap()

  • returns: <Promise> 若是成功在element上執行了 tap操做,則 Promise將會resolve。若是 element 已經從DOM上 detach掉了,則 Promise將會reject。

此方法將會在須要的時候將元素滾動到可視區域內,而後使用 touchscreen.tap來 tap element的中間位置。 若是 element 已經從DOM上 detach掉了,則將拋出錯誤。

elementHandle.toString()

elementHandle.type(text[, options])

  • text <string> 將要在聚焦元素內輸入的文本內容
  • options <Object>
    • delay <number> 輸入字符間的時間間隔。 默認是 0.
  • returns: <Promise>

聚焦element,而後爲每一個輸入的字符觸發 keydown, keypress/input, 以及 keyup事件。

爲了press一些特殊字符,例如 Control 或者 ArrowDown,請使用 elementHandle.press方法。

elementHandle.type('Hello'); // 快速輸入
elementHandle.type('World', {delay: 100}); // 輸入速度減慢以模擬真實輸入
複製代碼

下面是一個輸入文本並提交表單的例子:

const elementHandle = await page.$('input');
await elementHandle.type('some text');
await elementHandle.press('Enter');
複製代碼

elementHandle.uploadFile(...filePaths)

  • ...filePaths <...string> Sets the value of the file input these paths. If some of the filePaths are relative paths, then they are resolved relative to current working directory.
  • returns: <Promise>

This method expects elementHandle to point to an input element.

class: Request

當頁面發起請求的時候,例如請求網絡資源,下面這些事件都將會被觸發:

若是請求動做在某個地方失敗,那麼 requestfinished(也多是 response)事件會被 'requestfailed'所替代。

若是收到了重定向的響應指令,則當前請求結束,並觸發 requestfinished事件,而後會發起一個對新連接的獲取請求。

request.abort([errorCode])

  • errorCode <string> 可選的錯誤碼. 默認是 failed, 容許如下值:
    • aborted - 某個操做 aborted (來源於 user)
    • accessdenied - 訪問除網絡以外的資源的權限被拒絕
    • addressunreachable - The IP address is unreachable. 這一般意味着沒有路由到指定的主機或網絡。
    • connectionaborted - 因爲沒有收到發送的數據的ACK,致使鏈接超時
    • connectionclosed - 鏈接被關閉 (corresponding to a TCP FIN).
    • connectionfailed - 鏈接請求失敗.
    • connectionrefused - 鏈接請求被拒絕.
    • connectionreset - 鏈接請求被重置 (reset) (corresponding to a TCP RST).
    • internetdisconnected - 網絡鏈接丟失(也就是沒有網絡了)
    • namenotresolved - 沒法解析主機名。
    • timedout - 操做超時.
    • failed - 一個通用的故障發生
  • returns: <Promise>

Aborts request. To use this, 應確保請求攔截可用,使用 page.setRequestInterception來設置。

若是未啓用請求攔截,則將當即拋出異常。

request.continue([overrides])

  • overrides <Object> Optional request overwrites, which can be one of the following:
    • url <string> 若是設置此屬性值,則請求url將會被重置。
    • method <string> 若是設置此屬性值,則請求方式將會被重置。 (例如 GET or POST)
    • postData <string> 若是設置此屬性值,則post body將會被重置
    • headers <Object> 若是設置此屬性值,則 HTTP headers將會被重置
  • returns: <Promise>

攔截並改變請求參數。爲了確保此方法可用,請使用 page.setRequestInterception方法來保證請求攔截處於可用狀態(enable)。

若是未啓用請求攔截,則將當即拋出異常。

request.failure()

  • returns: <?Object> 請求失敗的緣由(若是有的話)
    • errorText <string> Human-readable error message, e.g. 'net::ERR_FAILED'.

若是請求失敗,則此方法返回請求失敗的緣由(若是有的話),而且觸發 requestfailed事件,若是請求成功,則此方法返回 null

下面是一個記錄全部請求失敗的例子:

page.on('requestfailed', request => {
  console.log(request.url() + ' ' + request.failure().errorText);
});
複製代碼

request.frame()

  • returns: <?Frame> A matching Frame object, or null if navigating to error pages.

request.headers()

  • returns: <Object> An object with HTTP headers associated with the request. All header names are lower-case.

request.isNavigationRequest()

當前請求是不是一個 navigation的請求(即,當前請求是否會觸發頁面跳轉或reload事件。)

request.method()

  • returns: <string> 請求方式 (例如,GET, POST等)

request.postData()

  • returns: <string> Request's post body, if any.

request.redirectChain()

A redirectChain is a chain of requests initiated to fetch a resource.

  • 若是沒有重定向,而且請求成功,則返回 空數組 []
  • If a server responds with at least a single redirect, then the chain will contain all the requests that were redirected.

redirectChain is shared between all the requests of the same chain.

例如,若是 http://example.com有一個重定向到 https://example.com的動做,則 redirectChain將包含一個請求:

const response = await page.goto('http://example.com');
const chain = response.request().redirectChain();
console.log(chain.length); // 1
console.log(chain[0].url()); // 'http://example.com'
複製代碼

若是https://google.com網站沒有重定向的動做,則 redirectChain將會是空數組:

const response = await page.goto('https://google.com');
const chain = response.request().redirectChain();
console.log(chain.length); // 0
複製代碼

request.resourceType()

包含全部被渲染引擎使用到的請求資源的類型,容許如下幾種: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other.

request.respond(response)

  • response <Object> 請求對應的響應對象
    • status <number> 響應狀態安, 默認是 200
    • headers <Object> 可選的響應頭
    • contentType <string> 若是設置了此屬性值,則至關因而 設置響應頭的 Content-Type
    • body <Buffer|string> 可選的 response body
  • returns: <Promise>

用給定的響應來完成請求。 爲了使此功能有效可用, 請設置 page.setRequestInterception,以確保請求攔截可用。若是請求攔截不可用,則將拋出錯誤。

下面是一個給請求響應 404狀態的例子:

await page.setRequestInterception(true);
page.on('request', request => {
  request.respond({
    status: 404,
    contentType: 'text/plain',
    body: 'Not Found!'
  });
});
複製代碼

NOTE 不支持對 dataURL請求的模擬響應。 對一個 dataURL請求使用 request.respond 將不會產生任何效果。

request.response()

  • returns: <?Response> 一個 matching Response object, 若是尚未收到響應,則返回 null

request.url()

  • returns: <string> URL of the request.

class: Response

Response class represents responses which are received by page.

response.buffer()

  • returns: <Promise<Buffer>> Promise which resolves to a buffer with response body.

response.fromCache()

若是響應數據來自於磁盤或者內存,則返回 true

response.fromServiceWorker()

若是響應數據來自於 service worker,則返回 true

response.headers()

  • returns: <Object> http響應頭對象. 全部的 header name 都是小寫.

response.json()

  • returns: <Promise<Object>> Promise which resolves to a JSON representation of response body.

若是響應數據體(response body)沒法使用 JSON.parse解析,則此方法將拋出錯誤。

response.ok()

包含一個用於標記數據響應是否成功(狀態碼爲 200-299)的布爾值。

response.request()

response.securityDetails()

  • returns: <?SecurityDetails> 若是是在 安全鏈接(https)上收到的響應數據,則爲 Security details,不然將是 null

response.status()

包含響應狀態碼(例如,200,表示響應成功)

response.text()

  • returns: <Promise<string>> Promise which resolves to a text representation of response body.

response.url()

包含響應的 URL

class: SecurityDetails

SecurityDetails class represents responses which are received by page.

securityDetails.issuer()

  • returns: <string> 帶有證書頒發機構名稱的字符串。

securityDetails.protocol()

  • returns: <string> 安全協議名, 例如 "TLS 1.2".

securityDetails.subjectName()

  • returns: <string> 證書籤發對象的名稱

securityDetails.validFrom()

  • returns: <number> UnixTime,安全證書開始生效的時間,用 Unix時間表示。

securityDetails.validTo()

  • returns: <number> UnixTime ,安全證書失效的時間,用 Unix時間表示。

class: Target

target.browser()

獲取 target(能夠認爲是page) 隸屬於的 browser。

target.browserContext()

The browser context the target belongs to.

target.createCDPSession()

Creates a Chrome Devtools Protocol session attached to the target.

target.opener()

Get the target that opened this target. Top-level targets return null.

target.page()

若是 target的類型不是 page 或者 background_page, 則返回 null

target.type()

返回 target的類型,能夠是 "page", "background_page", "service_worker", "browser" or "other"

target.url()

class: CDPSession

The CDPSession instances are used to talk raw Chrome Devtools Protocol:

  • protocol methods can be called with session.send method.
  • protocol events can be subscribed to with session.on method.

DevTools Protocol的文檔參見: DevTools Protocol Viewer.

const client = await page.target().createCDPSession();
await client.send('Animation.enable');
client.on('Animation.animationCreated', () => console.log('Animation created!'));
const response = await client.send('Animation.getPlaybackRate');
console.log('playback rate is ' + response.playbackRate);
await client.send('Animation.setPlaybackRate', {
  playbackRate: response.playbackRate / 2
});
複製代碼

cdpSession.detach()

將 cdpSession從 target上 detach掉,一旦cdpSession從 target上 detach掉了,則 the cdpSession object將不可再觸發任何事件,也再也不能夠用於發送信息

cdpSession.send(method[, params])

class: Coverage

Coverage用於收集記錄頁面使用了哪些 JavaScript 以及 CSS代碼。

下面的例子展現瞭如何獲取 頁面在初始化的時候,用到了所加載得 JavaScript 以及 CSS文件多少比例的內容:

// Enable both JavaScript and CSS coverage
await Promise.all([
  page.coverage.startJSCoverage(),
  page.coverage.startCSSCoverage()
]);
// Navigate to page
await page.goto('https://example.com');
// Disable both JavaScript and CSS coverage
const [jsCoverage, cssCoverage] = await Promise.all([
  page.coverage.stopJSCoverage(),
  page.coverage.stopCSSCoverage(),
]);
let totalBytes = 0;
let usedBytes = 0;
const coverage = [...jsCoverage, ...cssCoverage];
for (const entry of coverage) {
  totalBytes += entry.text.length;
  for (const range of entry.ranges)
    usedBytes += range.end - range.start - 1;
}
console.log(`Bytes used: ${usedBytes / totalBytes * 100}%`);
複製代碼

To output coverage in a form consumable by Istanbul, see puppeteer-to-istanbul.

coverage.startCSSCoverage(options)

  • options <Object> Set of configurable options for coverage
    • resetOnNavigation <boolean> Whether to reset coverage on every navigation. Defaults to true.
  • returns: <Promise> Promise that resolves when coverage is started

coverage.startJSCoverage(options)

  • options <Object> Set of configurable options for coverage
    • resetOnNavigation <boolean> Whether to reset coverage on every navigation. Defaults to true.
  • returns: <Promise> Promise that resolves when coverage is started

coverage.stopCSSCoverage()

  • returns: <Promise<Array<Object>>> Promise that resolves to the array of coverage reports for all stylesheets
    • url <string> StyleSheet URL
    • text <string> StyleSheet content
    • ranges <Array<Object>> StyleSheet ranges that were used. Ranges are sorted and non-overlapping.
      • start <number> A start offset in text, inclusive
      • end <number> An end offset in text, exclusive

NOTE CSS Coverage 不包括那些沒有 sourceURLs的動態加載得 style標籤。

coverage.stopJSCoverage()

  • returns: <Promise<Array<Object>>> Promise that resolves to the array of coverage reports for all non-anonymous scripts
    • url <string> Script URL
    • text <string> Script content
    • ranges <Array<Object>> Script ranges that were executed. Ranges are sorted and non-overlapping.
      • start <number> A start offset in text, inclusive
      • end <number> An end offset in text, exclusive

NOTE JavaScript Coverage 不包括匿名腳本。可是,會包括帶有sourceURLs的腳本。

相關文章
相關標籤/搜索