最近用到了 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的脚本。