最近用到了 Puppeteer 這個庫,既然用到了這個東西,順便也就把它的 API給看了一遍,爲了加深印象,在看的同時也就順便翻譯了一下,不過這API文檔的內容量仍是蠻大的,花費了好些時間纔看完,有些地方不知道怎麼翻譯比較好,因此也就沒翻譯,有的地方可能官方說得不怎麼詳細,我也加了一點主觀意見。javascript
Puppeteer是一個經過 DevTools Protocol 來控制 Chromium 或者 Chrome的 Node庫,並提供了一些高級API。css
這些API層級分明,並能提現出瀏覽器的自身結構。html
NOTE 在下面這個圖例中,淺色實體表明的結構還沒有在 Puppeteer中實現。java
Puppeteer
使用 DevTools Protocol與瀏覽器進行通訊。Browser
瀏覽器實例能夠包含多個瀏覽器上下文。BrowserContext
用於保持瀏覽器session,一個瀏覽器上下文能夠包含多個頁面。Page
一個Page最起碼包含一個frame,即 main frame,容許存在其餘的 frame,這些frame能夠用 [iframe]建立。Frame
一個 Frame最起碼有一個 Javascript執行上下文環境,即默認的執行上下文環境。Frame容許存在額外附加的上下文環境Worker
存在惟一的上下文環境,並可與 WebWorkers相互協做。(圖例來源: link)node
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。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();
});
複製代碼
options
<Object>
browserWSEndpoint
<string> a browser websocket endpoint to connect to.ignoreHTTPSErrors
<boolean> 在導航階段是否忽略 HTTPS錯誤,默認爲 false
.slowMo
<number> 經過改變此值來減緩 Puppeteer的操做速度,單位是毫秒,當你想知道具體發生了什麼狀況的時候,此參數將會比較有用。此方法將會爲 Puppeteer 附加上一個 Chromium 實例。git
options
<Object>
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD
階段 Chromium包被跳過下載,那麼此包也有多是不存在的。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.stdout
和 process.stderr
上。 默認爲 false
.userDataDir
<string> User Data Directory所在路徑。env
<Object> 明確指示瀏覽器實例可用的環境變量,默認爲 process.env
。devtools
<boolean> 是否爲每一個標籤頁自動打開 DevTools面板,若是爲 true
, 那麼 headless
選項將被設置爲 false
。pipe
<boolean> 經過一個 pipe
而不是 WebSocket
來連接瀏覽器實例,默認爲 false
。此方法根據給定的參數來啓動一個瀏覽器實例,此瀏覽器實例將會在其 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平臺上的差別。
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實例同時運行。
此方法經過發起一個 HEAD request來檢查目標版本是否可用。
revision
<string> 須要下載的瀏覽器的版本號.progressCallback
<function(number, number)> 此函數方法存在兩個參數:
此方法經過發起一個 GET請求來從目標 host下載指定版本的瀏覽器。
mac
, linux
, win32
、 win64
中的其中一個。revision
<string> 須要刪除的版本。若是指定的版本的瀏覽器並無被下載下來,此方法將會拋出錯誤(此錯誤可用 catch捕獲)。revision
<string> 但願獲取相關信息的瀏覽器的版本號。
returns: <Object>
revision
<string> 信息來源的版本號folderPath
<string> 提取所下載的瀏覽器包的目錄executablePath
<string> 目標版本的瀏覽器的運行目錄url
<string> 目標版本的瀏覽器的下載urllocal
<boolean> 目標版本的瀏覽器是否可在本地磁盤上獲取EventEmitter
當 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();
});
複製代碼
當 Puppeteer被從 Chromium實例上斷開時被觸發,包括以下幾種情形:
browser.disconnect
方法被調用當目標 url改變時觸發。
NOTE 包括在匿名瀏覽器上下文中目標URL改變。
當目標被建立時觸發, 例如,當一個新頁面經過 window.open
或者 browser.newPage
被打開時。
NOTE 包括在匿名瀏覽器上下文中目標的建立。
目標被銷燬時觸發, 例如,當一個頁面關閉時。
NOTE 包括在匿名瀏覽器上下文中目標的銷燬。
返回一個包含全部已經被打開的瀏覽器上下文的數組。 在一個最新被建立的瀏覽器中,將會返回一個惟一的BrowserContext的實例。
關閉 Chromium以及它全部的頁面(若是存在被打開的頁面的話)。Browser 對象將會被銷燬,而且再也不可用。
建立一個新的匿名瀏覽器上下文,這個匿名瀏覽器上下文不會與其餘瀏覽器上下文共享 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');
複製代碼
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 對象將會被銷燬,而且再也不可用。
返回一個新的 Page Promise對象,Page將在一個默認的瀏覽器上下文中建立。
"background_page"
, 將不會包含在此數組中,你可使用 target.page()方法來獲取到(不可見頁面)。puppeteer.connect
方法建立,那麼將會返回 null
。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梭組成的數組。
NOTE 可使用 page.setUserAgent來改變瀏覽器的 user agent。
HeadlessChrome/61.0.3153.0
的字符串。 對於non-headless 瀏覽器來講, 將返回一個相似於 Chrome/61.0.3153.0
的字符串。NOTE 此方法返回的字符串格式可能會在未來的版本中發生變化。
此方法返回的 瀏覽器 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.
EventEmitter
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();
複製代碼
當瀏覽器上下文中的某個target url改變時觸發。
當瀏覽器上下文中建立了一個新target時觸發,例如,當使用 window.open
或 browserContext.newPage
方法建立一個新頁面的時候。
當瀏覽器上下文中的某個target 被銷燬時觸發,例如當一個頁面被關閉時。
瀏覽器上下文歸屬的瀏覽器實例。
關閉瀏覽器上下文。全部屬於此瀏覽器上下文的target都將會一同銷燬。
NOTE 只有匿名瀏覽器上下文能夠被關閉(也就是隻有經過
createIncognitoBrowserContext
方法建立的匿名瀏覽器纔可使用此方法)。
NOTE 瀏覽器的默認瀏覽器上下文是不可關閉的。
在瀏覽器上下文中建立新頁面。
瀏覽器上下文中的全部有效target(例如Page頁面)組成的一個數組。
EventEmitter
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);
複製代碼
當頁面關閉的時候觸發。
當頁面上的Javascript腳本調用一些相似於 console.log
或 console.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'}));
複製代碼
當頁面上彈出 JavaScript對話框的時候觸發,例如 alert
, prompt
, confirm
或者 beforeunload
。Puppeteer可以經過 Dialog的 accept 或者 dismiss 方法來對此事件做出迴應。
當 JavaScript 的DOMContentLoaded
事件被觸發時觸發。
當頁面崩潰時觸發。
NOTE
error
事件在 Node中具備特殊的含義,具體細節參見 error events 。
當一個 frame 被附加到主頁面上時觸發。
當一個 frame 從主頁面上分離(刪除)時觸發。
當一個 frame 的url被定向到一個新的url上時觸發。
當 JavaScript 的load
事件被觸發時觸發。
當頁面上的JavaScript腳本調用 cnosole.timeStamp
時觸發。metrics的可選列表可見 page.metrics
。
當頁面上出現未捕獲的異常時觸發。
當頁面上發起一個請求的時候觸發。request對象是隻讀的,若是你想攔截並改造請求,參照 page.setRequestInterception
。
當請求失敗時觸發,例如,請求超時。
當請求完成時觸發。
當頁面收到請求的響應時觸發。
當頁面上產生一個新的 WebWorker線程時觸發。
當頁面上有 WebWorker線程結束時觸發。
selector
<string> 選擇器此方法在頁面上使用了 document.querySelector
。若是選擇器沒有匹配到元素,將會返回 null
。
page.mainFrame().$(selector)的快捷方法。
selector
<string> 選擇器此方法在頁面上使用了 document.querySelectorAll
。若是選擇器沒有匹配到元素,將會返回 []
。
page.mainFrame().$$(selector)的快捷方法。
selector
<string> 選擇器pageFunction
<function> 將在瀏覽器上下文中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的額外參數pageFunction
返回的結果。此方法在頁面上使用了 Array.from(document.querySelectorAll(selector))
,並將獲取到的結果當作 pageFunction
的第一個參數傳遞進去。
若是 pageFunction
返回的結果是一個 Promise,則page.$$eval
將會等到前者 resolve回一個結果後,纔會繼續返回本身的值。
例子:
const divsCounts = await page.$$eval('div', divs => divs.length);
複製代碼
selector
<string> 選擇器pageFunction
<function> 將在瀏覽器上下文中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的額外參數pageFunction
返回的結果。此方法在頁面上使用了 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)的快捷方法。
expression
<string> Expression to evaluate.根據給定的 Xpath表達式獲取 DOM元素。
page.mainFrame().$x(expression)的快捷方法。
options
<Object>
向頁面中增長指定 url或者 腳本內容的 script
標籤。
page.mainFrame().addScriptTag(options)的快捷方法。
options
<Object>
url
<string> 將要被添加的 style 的urlpath
<string> 將要被添加的 CSS文件的路徑. 若是 path
是相對路徑, 則其是相對於 current working directory。content
<string> 將要被添加的CSS腳本的內容。向頁面中添加一個 帶有指定 url的<link rel="stylesheet">
標籤,或者一個帶有內容的<style type="text/css">
標籤。
page.mainFrame().addStyleTag(options)的快捷方法。
Provide credentials for http authentication.
若是是無效的authentication,則返回 null
Brings page to front (activates tab).
獲取頁面所屬的 browser實例。
selector
<string> 將要被點擊的元素的 選擇器。若是選擇器匹配出了多個元素,則點擊事件只會做用在第一個匹配的元素上。options
<Object>
button
<string> left
, right
, or middle
, 默認是 left
(即便用左鍵、右鍵仍是中鍵進行點擊操做)clickCount
<number> 默認點擊一次。 更多參見UIEvent.detail。delay
<number> mousedown
和 mouseup
事件之間的時間間隔. 默認爲 0.此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
須要注意的是,若是所點擊的元素會觸發頁面跳轉,而且還調用了page.waitForNavigation()
方法,那麼你可能不會獲得指望的結果,正確的作法以下:
const [response] = await Promise.all([
page.waitForNavigation(waitOptions),
page.click(selector, clickOptions),
]);
複製代碼
page.mainFrame().click(selector[, options])的快捷方法。
options
<Object>
runBeforeUnload
<boolean> 默認爲false
. 是否在關閉前調用 before unload。page.close()
方法默認不調用 beforeunload句柄。
(這個方法的意思是,若是頁面上註冊了 onbeforeunload方法,那麼在關閉頁面時,將會調用這個onbeforeunload方法,若是 puppeteer.launch
的 headless
參數設置爲 true
,那麼你將看到頁面在關閉時,彈出了一個詢問是否離開頁面的對話框)。
NOTE 若是
runBeforeUnload
爲 true, 頁面在關閉時可能會彈出beforeunload
對話框, 而且這個對話框能夠被 page的 'dialog'事件捕獲到.
獲取頁面上包括 doctype在內的全部 HTML內容。
若是沒有提供 URLs,則此方法將會返回當前頁面URL的 cookies。 若是指定了URLs,則只有這些指定URLS上的cookies纔會被返回。
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>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中找到。
mediaType
<?string> 改變頁面CSS media的類型。容許的值有 'screen'
, 'print'
and null
,若是傳入null
則表示不進行模擬。pageFunction
<function|string> 將在 page context中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
若是傳遞給 page.evaluate
的 pageFunction
函數返回一個 Promise,則page.evaluate
將會等待獲得resolve後,纔會返回它本身的值。
若是傳遞給 page.evaluate
的 pageFunction
函數返回一個 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)的快捷方法。
pageFunction
<function|string> 在page context 中執行的函數。...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
as in-page object (JSHandle)。page.evaluate
和 page.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)的快捷方法。
pageFunction
<function|string> 在browser context中執行的函數。...args
<...Serializable> 傳遞給 pageFunction
的參數pageFunction
可能會在如下狀況下唄調用: Adds a function which would be invoked in one of the following scenarios:
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);
複製代碼
name
<string> 在 window對象中添加的函數的名字puppeteerFunction
<function> 將會在 Puppeteer's context中執行的函數。此方法將會在 window
對象中添加一個 名爲 name
的函數。 當被調用時,其將會在 node.js
中執行 puppeteerFunction
,而且返回一個 Promise,此Promise會 resolve
回 puppeteerFunction
的返回結果。
若是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();
});
複製代碼
selector
<string> 須要focus的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被focus。此方法將 focus給定 selector匹配到的元素。 若是根據給定的 selector沒有匹配到任何元素,將會拋出異常。
page.mainFrame().focus(selector)的快捷方法。
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條,則認爲導航結束。若是沒法 go back
,則 resolve回的數據爲 null
返回上一頁。
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條,則認爲導航結束。若是沒法 go forward
,則 resolve回的數據爲 null
跳轉到 history裏的下一頁。
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條,則認爲導航結束。若是在頁面跳轉過程當中發生如下狀況,則此方法將拋出錯誤:
NOTE
page.goto
方法要麼拋出一個錯誤,要麼返回 a main resource response,除非跳轉的連接是about:blank
, 這時候,此方法將返回null
。
NOTE 在 Headless mode下,此方法不支持 跳轉到 一個 PDF document。參見upstream issue.
selector
<string> 須要 hover的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被hover。此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法 hover匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
page.mainFrame().hover(selector)的快捷方法。
頁面是否被關閉。
navigations過程當中,Page一直存在一個 main frame。
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.
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 datetitle
文檔標題url
文檔urlpageNumber
當前頁碼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.
NOTE 生成pdf的操做只有Chrome瀏覽器纔有效。
page.pdf()
以 print
的 css media生成pdf,若是想生成一個 screen
media的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})
- 寬度爲100pxpage.pdf({width: '100px'})
- 寬度爲100pxpage.pdf({width: '10cm'})
- 寬度爲 10釐米全部可選的單位:
px
- pixelin
- inchcm
- centimetermm
- millimeterformat
屬性的可選值:
Letter
: 8.5in x 11inLegal
: 8.5in x 14inTabloid
: 11in x 17inLedger
: 17in x 11inA0
: 33.1in x 46.8inA1
: 23.4in x 33.1inA2
: 16.5in x 23.4inA3
: 11.7in x 16.5inA4
: 8.27in x 11.7inA5
: 5.83in x 8.27inA6
: 4.13in x 5.83inNOTE
headerTemplate
以及footerTemplate
的標籤有如下限制:
- Script tags inside templates are not evaluated.
- Page styles are not visible inside templates.
prototypeHandle
<JSHandle> A handle to the object 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)的快捷方法。
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條,則認爲導航結束。options
<Object> 此對象容許具有如下屬性:
path
<string> 截圖保存的地址路徑。 截圖的圖片類型會自動根據文件名擴展來肯定。若是 path
是相對路徑,則其應當是相對於 current working directory.。若是沒有提供此屬性值,則將不會保存截圖。type
<string> 指定截圖的文件類型。可選值有jpeg
和 png
。默認爲 'png'。quality
<number> 圖片質量, 值範圍爲 0-100。不適用於 png
圖片。fullPage
<boolean> 當值爲 true
的話,則將截取包括可滾動區域在內的全部頁面。默認爲 false
.clip
<Object> 用於肯定一個指定的裁剪範圍。必須具有如下屬性:
omitBackground
<boolean> 隱藏默認白色背景,並容許以透明方式截取屏幕截圖。 默認爲false
.encoding
<string> 圖片編碼方式,能夠是 base64
或者 binary
。默認爲 binary
.NOTE 在OS X系統上,截圖操做最少須要 1/6秒的時間。參見 crbug.com/741689 。
selector
<string> [select]標籤的選擇器...values
<...string> 選擇的值。若是 <select>
標籤具備 multiple
屬性, 全部的指定值都是有效值, 不然只會考慮第一個值。當全部提供的 values
值的選項(option)全被選中後會觸發 change
以及 input
事件。 若是根據所指定的選擇器selector
沒有匹配到一個 <select>
元素,將會拋出錯誤。 (這個方法就是用於控制 select的選擇)
page.select('select#colors', 'blue'); // 單選
page.select('select#colors', 'red', 'green', 'blue'); // 多選
複製代碼
Shortcut for page.mainFrame().select()
控制是否繞過頁面的Content-Security-Policy(內容安全策略)。
NOTE 繞過CSP的操做應該發生在CSP的初始化階段而不是執行階段。也就是說,在 navigating向目標主機以前就應該調用
page.setBypassCSP
方法。
是否使用資源緩存,默認啓用緩存。 Toggles ignoring cache for each request based on the enabled state. By default, caching is enabled.
timeout
<number> 導航超時時間。此方法能夠改變如下方法默認 30s的超時時間。
這些額外的 header頭將會被頁面發出的全部請求連接攜帶上。
NOTE page.setExtraHTTPHeaders 沒法保證請求header的順序。
NOTE 改變此值沒法影響到那些已經執行的 JS代碼。不過會在下次導航 navigation中徹底起做用。
啓用請求攔截將會使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 啓用請求攔截將會禁用頁面緩存(也就是請求再也不使用頁面緩存)。
NOTE 在某些的狀況下,設置 viewportin 將會致使頁面 reload 以便讓
isMobile
或者hasTouch
屬性生效。
若是一個瀏覽器中開啓了多個頁面,則每一個頁面都有其本身的 viewport大小。
此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.touchscreen方法tap匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
page.mainFrame().tap(selector)的快捷方法。
page.mainFrame().title()的快捷方法。
selector
<string> 文本框(包括 texarea和input)的選擇器。若是選擇器匹配出了多個元素,則只會選擇第一個匹配的元素上。text
<string> 將要輸入到文本框內的文字。options
<Object>
delay
<number> 按鍵輸入的間隔速度,單位爲ms。默認爲 0.Sends a keydown
, keypress
/input
, and keyup
event for each character in the text.
爲了按下一些特殊按鍵,例如 Control
或 ArrowDown
,請使用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.mainFrame().url()的快捷方法。
selectorOrFunctionOrTimeout
<string|number|function> A selector, predicate or timeout to wait foroptions
<Object> Optional waiting parameters...args
<...Serializable|JSHandle> pageFunction
的參數。根據第一個參數的不一樣,此方法可實現的場景以下:
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]])的快捷方法。
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
的額外參數。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]])的快捷方法。
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條,則認爲導航結束。適應於當頁面重定向到一個新的url或者reload的場景,例如,當執行了一段可能間接致使頁面跳轉的代碼:
const navigationPromise = page.waitForNavigation();
await page.click('a.my-link'); // 點擊此連接將會間接致使頁面跳轉
await navigationPromise; // 當頁面跳轉完畢後,將會 resolve
複製代碼
NOTE 使用 History API 方法改變 URL也會被當成是一個 navigation。
selector
<string> 被等待的元素的選擇器selectoroptions
<Object> 可選參數:
等到 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])的快捷方法。
xpath
<string> 匹配xpath的元素options
<Object> 可選參數以下:
等到匹配 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])的快捷方法。
NOTE 不包括 ServiceWorkers。
The Worker class represents a WebWorker. workercreated
和 workerdestroyed
事件將會被當作 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());
複製代碼
pageFunction
<function|string> worker context中將被執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
函數的返回值。若是pageFunction
返回的值是一個 Promise,則 worker.evaluate
方法將會等到前者 resolve
後,纔會返回它本身的值。
若是pageFunction
返回的值是一個 non-Serializable 的值, 則 worker.evaluate
將會 resolves undefined
。
(await worker.executionContext()).evaluate(pageFunction, ...args)的快捷方法。
pageFunction
<function|string> 將在page context中執行的函數。...args
<...Serializable|JSHandle> 傳遞給 pageFunction
函數的參數。pageFunction
as in-page object (JSHandle)worker.evaluate
和 worker.evaluateHandle
之間惟一的區別在於,worker.evaluateHandle
返回一個 in-page object (JSHandle)
若是pageFunction
返回的值是一個 Promise,則 worker.evaluateHandle
方法將會等到前者 resolve
後,纔會返回它本身的值。
(await worker.executionContext()).evaluateHandle(pageFunction, ...args)的快捷方法。
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
key
<string> 按下的按鍵名稱, such as ArrowLeft
. 參見 USKeyboardLayout 獲取按鍵名稱列表。options
<Object>
text
<string> 若是指定了此屬性值, generates an input event with this text.觸發 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
鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。
key
<string> 須要按下的按鍵的名稱, 例如 ArrowLeft
. 更多按鍵名稱列表參見 USKeyboardLayout 。options
<Object>
若是 key
值是一個單個字母,而且沒有除了 Shift
以外的修飾按鍵被按下,那麼將會繼續觸發 keypress
/input
事件。能夠指定 'text'選項以強制生成輸入事件。
NOTE 修飾鍵將會影響
keyboard.press
的效果。若是你按住Shift
鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。
keyboard.down
和 keyboard.up
的快捷方法。
觸發 keypress
和 input
事件,不會觸發 keydown
或者 keyup
事件。
page.keyboard.sendCharacter('嗨');1
複製代碼
NOTE 修飾鍵將會影響
keyboard.sendCharacter
的效果。若是你按住Shift
鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。
輸入文本的時候,每一個字符都會觸發 keydown
, keypress
/input
, 以及 keyup
事件。
若是想要輸按下特殊字符,例如Control
以及 ArrowDown
,參見keyboard.press
。
page.keyboard.type('Hello'); // 快速輸入
page.keyboard.type('World', {delay: 100}); // 模擬真實輸入
複製代碼
NOTE 修飾鍵不會影響
keyboard.type
的效果。也就是說,調用此方法時,就算你已經按住了Shift
鍵,也不會將你想要輸入的文本全都強制變成大寫的。
key
<string> 須要釋放的按鍵的名稱, 例如 ArrowLeft
. 更多按鍵名稱列表參見 USKeyboardLayout。觸發 keyup
事件。
x
<number>y
<number>options
<Object>
button
<string> left
, right
, 或者 middle
, 默認是 left
。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)clickCount
<number> 點擊次數,默認是 1. 參見 UIEvent.detail.delay
<number> mousedown
和 mouseup
之間的時間間隔(ms).默認是 0.mouse.move
, mouse.down
以及 mouse.up
的聯合方法。
options
<Object>
button
<string> left
, right
, 或者 middle
, 默認是 left
。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)clickCount
<number>默認是 1. 參見 UIEvent.detail.觸發 mousedown
事件。
x
<number>y
<number>options
<Object>
steps
<number>默認是 1. Sends intermediate mousemove
events.觸發 mousemove
事件。
options
<Object>
button
<string> left
, right
, 或者 middle
, 默認是 left
。clickCount
<number> 默認是 1. 參見 UIEvent.detail.觸發 mouseup
事件。
Dispatches a touchstart
and touchend
event.
你可使用 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();
複製代碼
每一個瀏覽器一次只能執行一個跟蹤任務。
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'));
});
複製代碼
promptText
<string> 在提示框中輸入的文件內容。。若是dialog的類型不是prompt(提示框),則此方法將不起任何做用。alert
, beforeunload
, confirm
or prompt
.ConsoleMessage objects are dispatched by page via the 'console' event.
容許如下值: 'log'
, 'debug'
, 'info'
, 'error'
, 'warning'
, 'dir'
, 'dirxml'
, 'table'
, 'trace'
, 'clear'
, 'startGroup'
, 'startGroupCollapsed'
, 'endGroup'
, 'assert'
, 'profile'
, 'profileEnd'
, 'count'
, 'timeEnd'
。
不管在哪一個時間點,都可以經過page.mainFrame() 和 frame.childFrames()方法來獲取的頁面當前的 frame tree。
Frame對象的生命週期,由三個事件組成:
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 + ' ');
}
});
複製代碼
selector
<string> Selector to query page for在 frame上搜索元素。若是沒有找到所需匹配的元素,則resolve會 null
selector
<string> Selector to query page for此方法使用了 document.querySelectorAll
,若是沒有匹配到任何元素,則resolve回 []
selector
<string> frame上目標元素的 selectorpageFunction
<function> 將在 browser context執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的額外參數pageFunction
此方法使用了 Array.from(document.querySelectorAll(selector))
,並將其返回的結果做爲 pageFunction
函數的第一個參數傳遞進去。
若是 pageFunction
返回的結果是一個 Promise,則 frame.$$eval
將會等到前者成功resolve,而後再返回本身的值。
Examples:
const divsCounts = await frame.$$eval('div', divs => divs.length);
複製代碼
selector
<string> frame上目標元素的 selectorpageFunction
<function> 將在 browser context執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的額外參數pageFunction
此方法使用了 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);
複製代碼
expression
<string> Expression to evaluate.此方法用於執行給定的 XPath 表達式。
options
<Object>
url
<string> 須要被增長的script標籤的urlpath
<string> 將要被添加的JavaScript文件的路徑. 若是 path
是相對路徑, 則其是相對於 current working directory。content
<string> 將要被添加的 JavaScript腳本的內容。type
<string> 腳本類型. 若是是 'module' ,則將導入的是JS的 ES6模塊。更多參見 [script]向frame中增長指定 url或者 腳本內容的 script
標籤。
options
<Object>
url
<string> 將要被添加的 style 的urlpath
<string>將要被添加的 CSS文件的路徑. 若是 path
是相對路徑, 則其是相對於 current working directory。content
<string> 將要被添加的CSS腳本的內容。向頁面中添加一個 帶有指定 url的<link rel="stylesheet">
標籤,或者一個帶有內容的<style type="text/css">
標籤。
selector
<string> 將要被點擊的元素的 選擇器。若是選擇器匹配出了多個元素,則點擊事件只會做用在第一個匹配的元素上。options
<Object>
button
<string> left
, right
, or middle
, 默認是 left
(即便用左鍵、右鍵仍是中鍵進行點擊操做)clickCount
<number> 默認點擊一次。 更多參見UIEvent.detail。delay
<number> mousedown
和 mouseup
事件之間的時間間隔. 默認爲 0.此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
須要注意的是,若是所點擊的元素會觸發頁面跳轉,而且還調用了page.waitForNavigation()
方法,那麼你可能不會獲得指望的結果,正確的作法以下:
const [response] = await Promise.all([
page.waitForNavigation(waitOptions),
frame.click(selector, clickOptions),
]);
複製代碼
獲取frame包括doctype在內的完整HTML內容
pageFunction
<function|string> 將在 browser context中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
若是傳遞給 frame.evaluate
的 pageFunction
函數返回一個 Promise,則frame.evaluate
將會等待獲得resolve後,纔會返回它本身的值。
若是傳遞給 frame.evaluate
的 pageFunction
函數返回一個 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();
複製代碼
pageFunction
<function|string> 在page context 中執行的函數。...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
as in-page object (JSHandle)frame.evaluate
和 paframege.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();
複製代碼
selector
<string> 須要focus的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被focus。此方法將 focus給定 selector匹配到的元素。 若是根據給定的 selector沒有匹配到任何元素,將會拋出異常。
selector
<string> 須要 hover的元素的選擇器。 若是此選擇器匹配到了多個元素,則只有第一個匹配的元素纔會被hover。此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法 hover匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
若是 frame已經detached了,則返回 true
, 不然返回 false
返回 frame的name屬性值。
若是name屬性不存在或者爲空字符串,則返回 id屬性的值,若是 id屬性也不存在或者爲空字符串,則返回空字符串。
NOTE 此方法的返回值只會在frame被建立後計算一次,若是稍後frame的相關屬性(name或者id)發生變化,此方法的返回值也不會改變。
null
。selector
<string> [select]標籤的選擇器...values
<...string> 選擇的值。若是 <select>
標籤具備 multiple
屬性, 全部的指定值都是有效值, 不然只會考慮第一個值。當全部提供的 values
值的選項(option)全被選中後會觸發 change
以及 input
事件。 若是根據所指定的選擇器selector
沒有匹配到一個 <select>
元素,將會拋出錯誤。 (這個方法就是用於控制 select的選擇)
frame.select('select#colors', 'blue'); // 單選
frame.select('select#colors', 'red', 'green', 'blue'); // 多選
複製代碼
此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.touchscreen方法tap匹配到的元素的中心位置。 若是沒有匹配到元素,則將拋出一個錯誤。
selector
<string> 文本框(包括 texarea和input)的選擇器。若是選擇器匹配出了多個元素,則只會選擇第一個匹配的元素上。text
<string> 將要輸入到文本框內的文字。options
<Object>
delay
<number> 按鍵輸入的間隔速度,單位爲ms。默認爲 0.Sends a keydown
, keypress
/input
, and keyup
event for each character in the text.
爲了按下一些特殊按鍵,例如 Control
或 ArrowDown
,請使用keyboard.press
。
frame.type('#mytextarea', 'Hello'); // 快速輸入
frame.type('#mytextarea', 'World', {delay: 100}); // 減緩輸入速度以模擬真實輸入
複製代碼
返回 frame的url
selectorOrFunctionOrTimeout
<string|number|function> A selector, predicate or timeout to wait foroptions
<Object> Optional waiting parameters...args
<...Serializable|JSHandle> pageFunction
的參數。根據第一個參數的不一樣,此方法可實現的場景以下:
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。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
的額外參數。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();
});
複製代碼
selector
<string> 被等待的元素的選擇器selectoroptions
<Object> 可選參數
等到 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();
});
複製代碼
xpath
<string> 匹配xpath的元素options
<Object> 可選參數以下:
等到匹配 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();
});
複製代碼
The class represents a context for JavaScript execution. Examples of JavaScript contexts are:
pageFunction
<function|string> 在 executionContext
中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
函數的結果。若是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'.
複製代碼
pageFunction
<function|string> 將在executionContext
中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
函數的參數。pageFunction
as in-page object (JSHandle)executionContext.evaluate
和 executionContext.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();
複製代碼
NOTE 並非每個 execution context都存在一個frame。例如, workers 以及 extensions 都存在 execution context,可是沒有 frame。
prototypeHandle
<JSHandle> A handle to the object 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();
複製代碼
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
方法的參數。
若是當前 object handle是ElementHandle的實例,則將返回object handle自己,不然返回 null
此方法用於斷開element handle的引用
返回 handle所在的執行上下文。
此方法返回一個由屬性名稱做爲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();
複製代碼
從引用的object中獲取給定 propertyName
對應的 property。
返回 object的 json。若是 object具備toJSON
函數方法,也不會調用此函數方法. Returns a JSON representation of the object. If the object has a
NOTE 若是引用的object沒法字符串化,則此方法將返回空 JSON對象。若是引用的object存在循環引用,則將拋出錯誤。
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
方法的參數。
selector
<string> 目標元素的 selector此方法將在頁面上使用element.querySelector
,若是沒有匹配到任何元素,則將resolve 回null
selector
<string> 目標元素的 selector此方法將在頁面上使用element.querySelectorAll
,若是沒有匹配到任何元素,則將resolve 回[]
selector
<string> 目標元素的 selectorpageFunction
<function> 將在 browser context中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
函數的返回值。此方法將在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!']);
複製代碼
selector
<string> 目標元素的 selectorpageFunction
<function> 將在 browser context中執行的函數...args
<...Serializable|JSHandle> 傳遞給 pageFunction
的參數pageFunction
函數的返回值。此方法將在 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');
複製代碼
expression
<string> Expression to evaluate.The method evaluates the XPath expression relative to the elementHandle. If there are no such elements, the method will resolve to an empty array.
此方法返回 element 的 bounding box(即座標和長、寬信息,座標是相對於main frame的),若是element不可見(not visible),則返回 null
此方法返回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.
options
<Object>
button
<string> left
, right
, 或者 middle
, 默認是 left
。(意思是用鼠標的哪一個按鍵進行點擊操做,左鍵、右鍵或者中鍵)clickCount
<number> 點擊次數,默認是 1. 參見 UIEvent.detail.delay
<number> mousedown
和 mouseup
之間的時間間隔(ms).默認是 0.此方法將會根據給定的選擇器匹配到元素,若是所匹配到的元素不在視界內,將會將其滾動到視界內,而後使用 page.mouse方法點擊匹配到的元素的中心位置。 若是element 已經從DOM上 detach掉了,則將拋出一個錯誤。
此方法斷開 element handle的引用
調用 element的focus 方法。
此方法返回一個由屬性名稱做爲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
複製代碼
key
<string> 須要按下的按鍵的名稱, 例如 ArrowLeft
. 更多按鍵名稱列表參見 USKeyboardLayout。options
<Object>
聚焦在 element上,而後使用 keyboard.down
以及 keyboard.up
方法。
若是 key
值是一個單個字母,而且沒有除了 Shift
以外的修飾按鍵被按下,那麼將會繼續觸發 keypress
/input
事件。能夠指定 'text'選項以強制生成輸入事件。
NOTE 修飾鍵將會影響
elementHandle.press
的效果。若是你按住Shift
鍵,而後再按其餘的字母鍵,則你將輸入一個大寫的字母。
options
<Object> 參數和 page.screenshot方法的參數相似。此方法將會在須要的時候將元素滾動到可視區域內,而後使用 page.screenshot方法來對 element進行截圖操做。 若是 element 已經從DOM上 detach掉了,則此方法將拋出錯誤。
此方法將會在須要的時候將元素滾動到可視區域內,而後使用 touchscreen.tap來 tap element的中間位置。 若是 element 已經從DOM上 detach掉了,則將拋出錯誤。
聚焦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');
複製代碼
...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.This method expects elementHandle
to point to an input element.
當頁面發起請求的時候,例如請求網絡資源,下面這些事件都將會被觸發:
若是請求動做在某個地方失敗,那麼 requestfinished
(也多是 response
)事件會被 'requestfailed'所替代。
若是收到了重定向的響應指令,則當前請求結束,並觸發 requestfinished
事件,而後會發起一個對新連接的獲取請求。
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
- 一個通用的故障發生Aborts request. To use this, 應確保請求攔截可用,使用 page.setRequestInterception
來設置。
若是未啓用請求攔截,則將當即拋出異常。
overrides
<Object> Optional request overwrites, which can be one of the following:
攔截並改變請求參數。爲了確保此方法可用,請使用 page.setRequestInterception
方法來保證請求攔截處於可用狀態(enable)。
若是未啓用請求攔截,則將當即拋出異常。
errorText
<string> Human-readable error message, e.g. 'net::ERR_FAILED'
.若是請求失敗,則此方法返回請求失敗的緣由(若是有的話),而且觸發 requestfailed
事件,若是請求成功,則此方法返回 null
,
下面是一個記錄全部請求失敗的例子:
page.on('requestfailed', request => {
console.log(request.url() + ' ' + request.failure().errorText);
});
複製代碼
當前請求是不是一個 navigation的請求(即,當前請求是否會觸發頁面跳轉或reload事件。)
A redirectChain
is a chain of requests initiated to fetch a resource.
[]
。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
複製代碼
包含全部被渲染引擎使用到的請求資源的類型,容許如下幾種: document
, stylesheet
, image
, media
, font
, script
, texttrack
, xhr
, fetch
, eventsource
, websocket
, manifest
, other
.
用給定的響應來完成請求。 爲了使此功能有效可用, 請設置 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
將不會產生任何效果。
Response class represents responses which are received by page.
若是響應數據來自於磁盤或者內存,則返回 true
若是響應數據來自於 service worker,則返回 true
若是響應數據體(response body)沒法使用 JSON.parse
解析,則此方法將拋出錯誤。
包含一個用於標記數據響應是否成功(狀態碼爲 200-299)的布爾值。
null
包含響應狀態碼(例如,200,表示響應成功)
包含響應的 URL
SecurityDetails class represents responses which are received by page.
獲取 target(能夠認爲是page) 隸屬於的 browser。
The browser context the target belongs to.
Creates a Chrome Devtools Protocol session attached to the target.
Get the target that opened this target. Top-level targets return null
.
若是 target的類型不是 page
或者 background_page
, 則返回 null
返回 target的類型,能夠是 "page"
, "background_page"
, "service_worker"
, "browser"
or "other"
EventEmitter
The CDPSession
instances are used to talk raw Chrome Devtools Protocol:
session.send
method.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從 target上 detach掉,一旦cdpSession從 target上 detach掉了,則 the cdpSession object將不可再觸發任何事件,也再也不能夠用於發送信息
method
<string> protocol method nameparams
<Object> Optional method parametersCoverage用於收集記錄頁面使用了哪些 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.
options
<Object> Set of configurable options for coverage
resetOnNavigation
<boolean> Whether to reset coverage on every navigation. Defaults to true
.options
<Object> Set of configurable options for coverage
resetOnNavigation
<boolean> Whether to reset coverage on every navigation. Defaults to true
.NOTE CSS Coverage 不包括那些沒有 sourceURLs的動態加載得 style標籤。
NOTE JavaScript Coverage 不包括匿名腳本。可是,會包括帶有sourceURLs的腳本。