Puppeteer APIv1.11 中文版

Released APIs: v1.1.1 | v1.1.0 | v1.0.0 | v0.13.0 | v0.12.0 | v0.11.0 | v0.10.2 | v0.10.1 | v0.10.0 | v0.9.0

Puppeteer API v<!-- GEN:version -->1.1.1-post<!-- GEN:stop--> **NOT RELEASED**

NOTE 此版本的API 预计将会发布 于2018年3月15日.

Table of Contents

<!-- toc -->

<!-- tocstop -->

Overview

Puppeteer是一个Node库,它提供了一个高级API来通过DevTools协议控制Chromium或Chrome。

Puppeteer API是分层次的,反映了浏览器结构。

puppeteer overview

  • Puppeteer 使用浏览器进行通信 DevTools Protocol.
  • Browser 实例可以拥有多个页面。
  • Page 至少有一个框架:主框架。 可能有其他框架由创建 iframe or frame tags.
  • Frame 至少有一个执行上下文 - 默认执行上下文 - 执行框架的JavaScript。 一个框架可能有其他与之相关的执行上下文 extensions.

(图源: link)

环境变量

Puppeteer 寻找某些环境变量 以帮助其运作。这些变量既可以在环境中设置,也可以在 npm config.

  • HTTP_PROXY, HTTPS_PROXY, NO_PROXY - 定义用于下载和运行Chromium的HTTP代理设置。
  • PUPPETEER_SKIP_CHROMIUM_DOWNLOAD - 请勿在安装步骤中下载捆绑的Chromium。
  • PUPPETEER_DOWNLOAD_HOST - 覆盖用于下载Chromium的URL的主机部分

class: Puppeteer

Puppeteer模块提供了一种启动Chromium实例的方法。 以下是使用Puppeteer驱动自动化的典型示例:

const puppeteer = require('puppeteer');

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

此方法将Puppeteer添加到现有的Chromium实例。

puppeteer.createBrowserFetcher([options])
  • options <Object>
    • host <string> 要使用的下载主机。默认为 https://storage.googleapis.com.
    • path <string> 下载文件夹的路径。 默认为 <root>/.local-chromium, 其中<root>是puppeteer的软件包根目录。
    • platform <string> 可能的值是:macwin32win64linux。默认为当前平台。
  • returns: <BrowserFetcher>
puppeteer.defaultArgs()
  • returns: <Array<string>> Chromium将与之一起启动的默认标志。
puppeteer.executablePath()
  • returns: <string> Puppeteer希望找到捆绑的Chromium的路径。如果使用[PUPPETEER_SKIP_CHROMIUM_DOWNLOAD]跳过下载,那么Chromium可能不存在(#environment-variables).
puppeteer.launch([options])
  • options <Object> 在浏览器上设置的一组可配置选项。可以有以下字段:
    • ignoreHTTPSErrors <boolean> 是否在导航期间忽略HTTPS错误。默认为 false.
    • headless <boolean> 是否在headless mode中运行浏览器。 默认为 true unless the devtools option is true.
    • executablePath <string> 可运行Chromium或Chrome可执行文件的路径,而不是捆绑的Chromium。 If executablePath is a relative path, then it is resolved relative to current working directory.
    • slowMo <number> 将Puppeteer操作减少指定的毫秒数。有用,这样你就可以看到发生了什么。
    • args <Array<string>> 传递给浏览器实例的其他参数。可以找到Chromium标志的列表 here.
    • ignoreDefaultArgs <boolean>不要使用puppeteer.defaultArgs()。 Dangerous option; use with care. 默认为 false.
    • handleSIGINT <boolean> 在Ctrl-C上关闭浏览器进程。 默认为 true.
    • handleSIGTERM <boolean> 关闭SIGTERM上的浏览器进程。 默认为 true.
    • handleSIGHUP <boolean> 关闭SIGHUP上的浏览器进程。 默认为 true.
    • timeout <number> 等待浏览器实例启动的最长时间(以毫秒为单位)。默认为 30000 (30 seconds). Pass 0 to disable timeout.
    • dumpio <boolean> 是否将浏览器进程标准输出和标准错误输入到process.stdoutprocess.stderr中。 默认为 false.
    • userDataDir <string> 路径 User Data Directory.
    • env <Object> 指定浏览器可见的环境变量。 默认为 process.env.
    • devtools <boolean> 是否为每个选项卡自动打开DevTools面板。 如果此选项为true,则headless选项将设置为false
  • returns: <Promise<Browser>> 承诺解决浏览器实例。

该方法启动具有给定参数的浏览器实例。当父节点node.js进程关闭时,浏览器将被关闭。

NOTE Puppeteer也可以用来控制Chrome浏览器,但它与捆绑在一起的Chromium版本效果最好。 不能保证它可以与任何其他版本一起使用。极其谨慎地使用executablePath选项。

如果Google Chrome(而不是Chromium)是首选的, Chrome CanaryDev Channel版本

In puppeteer.launch([options]) above, any mention of Chromium 也适用于 Chrome.

See this article 了解Chromium和Chrome之间的区别。This article 描述了Linux用户的一些差异。

class: BrowserFetcher

BrowserFetcher可以下载和管理不同版本的Chromium。

BrowserFetcher在指定精确版本的Chromium的修订字符串上运行,例如, "533271". 修订字符串可以从中获得 omahaproxy.appspot.com.

有关如何使用BrowserFetcher下载特定版本的Chromium并运行的示例

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

NOTE BrowserFetcher不适用于与共享相同下载目录的其他BrowserFetcher实例同时使用。

browserFetcher.canDownload(revision)
  • revision <string> 一个检查可用性的修订。
  • returns: <Promise<boolean>> 如果可以从主机下载修订版,则返回true

该方法启动一个HEAD请求来检查修订版是否可用。

browserFetcher.download(revision[, progressCallback])
  • revision <string> 下载修订。
  • progressCallback <function(number, number)> 将用两个参数调用的函数:
    • downloadedBytes <number> 已经下载了多少字节
    • totalBytes <number> 总下载量有多大。
  • returns: <Promise<Object>> 下载并提取修订版时解决修订信息
    • revision <string> 信息创建的修订版本
    • folderPath <string> 提取的修订文件夹的路径
    • executablePath <string> 修订可执行文件的路径
    • url <string> 这个版本的URL可以从中下载
    • local <boolean> 修订版是否在本地可用磁盘上

该方法启动一个GET请求以从主机下载修订版本。

browserFetcher.localRevisions()
browserFetcher.platform()
  • returns: <string> 返回maclinuxwin32win64中的一个。
browserFetcher.remove(revision)
  • revision <string> 修改删除。 如果尚未下载修订版,该方法将抛出。
  • returns: <Promise> 在修订版本被删除时解决。
browserFetcher.revisionInfo(revision)
  • revision <string> 修改以获取信息。
  • returns: <Object>
    • revision <string> 信息创建的修订版本
    • folderPath <string> 提取的修订文件夹的路径
    • executablePath <string> 修订可执行文件的路径
    • url <string> 这个版本的URL可以从中下载
    • local <boolean> 修订版是否在本地可用磁盘上

class: Browser

当Puppeteer连接到Chromium实例时创建浏览器, 通过 puppeteer.launch or puppeteer.connect.

使用Browser创建Page的示例:

const puppeteer = require('puppeteer');

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

断开连接并重新连接到Browser的示例:

const puppeteer = require('puppeteer');

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

  // Use the endpoint to reestablish a connection
  const browser2 = await puppeteer.connect({browserWSEndpoint});
  // Close Chromium
  await browser2.close();
});
event: 'disconnected'

当Puppeteer与Chromium实例断开连接时发出。 这可能由于以下原因而发生:

event: 'targetchanged'

Emitted 当目标的网址发生变化时。

event: 'targetcreated'

Emitted 当一个目标被创建时,例如当一个新页面被打开时 window.open or browser.newPage.

event: 'targetdestroyed'

Emitted 当一个目标被破坏时,例如当一个页面关闭时。

browser.close()

关闭 Chromium及其所有页面(如果有的话)被打开。 该 Browser 对象本身被认为是 disposed 不能再使用了.

browser.disconnect()

将浏览器中的Puppeteer断开连接,但Chromium进程仍在运行。在调用disconnect后,Browser对象被认为已经处理掉,不能再使用了。

browser.newPage()
browser.pages()
browser.process()
browser.targets()
  • returns: <Array<Target>> 所有活动目标的数组。
browser.userAgent()
  • returns: <Promise<string>> 承诺将解析为浏览器的原始用户代理。

NOTE 页面可以覆盖浏览器用户代理 page.setUserAgent

browser.version()
  • returns: <Promise<string>> 对于 headless Chromium, 这与之类似HeadlessChrome/61.0.3153.0. 对于 non-headless, 这与之类似 Chrome/61.0.3153.0.

NOTE browser.version()的格式可能会随着未来版本的Chromium而改变。

browser.wsEndpoint()
  • returns: <string> 浏览器websocket网址。

可用作参数的浏览器websocket端点 puppeteer.connect. 格式是 ws://${host}:${port}/devtools/browser/<id>

你可以找到 webSocketDebuggerUrlhttp://${host}:${port}/json/version. 了解更多关于 devtools protocolbrowser endpoint.

class: 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();
});

Page类发出各种事件(如下所述),可以使用Node的任何本机进行处理 EventEmitter 方法, such as on or once.

这个例子记录了单个页面load事件的消息:

page.once('load', () => console.log('Page loaded!'));
event: 'console'

当页面内的JavaScript调用控制台API方法之一时发出,例如 console.log or console.dir. 如果页面抛出错误或警告,也会发出。

传递给console.log的参数显示为事件处理函数的参数。

处理console事件的一个例子:

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

当出现JavaScript对话框时发出, such as alert, prompt, confirm or beforeunload. Puppeteer 可以通过Dialog的回应对话 accept or dismiss methods.

event: 'domcontentloaded'

当JavaScript发出时 DOMContentLoaded 事件被派遣。

event: 'error'

页面崩溃时发出。

NOTE error 事件在节点中有特殊的含义, see error events for details.

event: 'frameattached'

当连接框架时发射。

event: 'framedetached'

当框架分离时发射。

event: 'framenavigated'

Emitted当一个框架被导航到一个新的url。

event: 'load'

Emitted 当JavaScript load 事件被 调度.

event: 'metrics'
  • <Object>
    • title <string> 标题传递给 console.timeStamp.
    • metrics <Object> 包含指标作为键/值对的对象。 度量值的值是<number>类型。

Emitted 当JavaScript代码调用时 console.timeStamp. 有关度量标准的列表 see page.metrics.

event: 'pageerror'

在页面内发生未捕获的异常时发出。

event: 'request'

当页面发出请求时发出。 request对象是只读的。 为了拦截和改变请求, see page.setRequestInterception.

event: 'requestfailed'

当请求失败时,例如通过超时发送.

event: 'requestfinished'

当请求成功完成时发出。

event: 'response'

收到Response时发出。

page.$(selector)

该方法在页面内运行document.querySelector。如果没有元素匹配选择器,则返回值解析为null

快捷键 page.mainFrame().$(selector).

page.$$(selector)

该方法运行 document.querySelectorAll 在页面内. 如果没有元素匹配选择器, 返回值解析为[]

Shortcut for page.mainFrame().$$(selector).

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

该方法在页面内运行document.querySelectorAll,并将其作为第一个参数传递给pageFunction

如果pageFunction返回Promise,那么page.$$eval将等待承诺解析并返回它的值。

例子:

const divsCounts = await page.$$eval('div', divs => divs.length);
page.$eval(selector, pageFunction[, ...args])

该方法在页面内运行document.querySelector,并将其作为第一个参数传递给pageFunction。 如果没有与selector匹配的元素,则该方法将引发错误。

如果pageFunction返回一个Promise,那么page.$eval会等待承诺解析并返回它的值。

Examples:

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

快捷键page.mainFrame().$eval(selector, pageFunction).

page.$x(expression)

该方法评估XPath表达式。

快捷键 page.mainFrame().$x(expression)

page.addScriptTag(options)
  • options <Object>
    • url <string> 要添加的脚本的URL。
    • path <string> 将JavaScript文件注入frame的路径. 如果path是相对路径,则相对于current working directory.
    • content <string> 被注入框架 的 原始的JavaScript内容 .
  • returns: <Promise<ElementHandle>> 当脚本的onload触发或者脚本内容被注入到框架中时,它解析为添加的标记。

<script>标签添加到具有所需网址或内容的页面中。

快捷键 page.mainFrame().addScriptTag(options).

page.addStyleTag(options)
  • options <Object>
    • url <string> <link>标签的URL。
    • path <string> 将CSS文件注入frame的路径。 如果path是一个相对路径,那么它相对于它被解析current working directory.
    • content <string> 被注入框架 的 原始的 Css 内容 .
  • returns: <Promise<ElementHandle>> 当样式表的onload被触发时或CSS内容被注入到框架中时,它解析为添加的标签。

添加一个 <link rel="stylesheet"> 使用所需的网址标记到网页中 或 一个 <style type="text/css"> 标记内容。

快捷键 page.mainFrame().addStyleTag(options).

page.authenticate(credentials)

提供凭据 http authentication.

禁用身份验证, 传递 null.

page.bringToFront()

将页面导向前(激活标签)。

page.click(selector[, options])
  • selector <string> selector搜索要单击的元素。如果有多个元素满足选择器,则会首先点击。
  • options <Object>
    • button <string> left, right, or middle, 默认为 left.
    • clickCount <number> 默认为 1. See UIEvent.detail.
    • delay <number> 在毫秒内在mousedownmouseup之间等待的时间。 默认为 0.
  • returns: <Promise> 当匹配selector的元素被成功的点击时,Promise会解析。 如果没有匹配selector的元素,Promise将被拒绝。

此方法使用selector获取元素,如果需要将其滚动到视图中,然后使用page.mouse单击元素的中心。 如果没有与selector匹配的元素,则该方法将引发错误。

请记住,如果click()触发一个导航事件,并且有一个单独的page.waitForNavigation()承诺被解析,那么最终可能会导致竞争条件,从而产生意想不到的结果。 点击和等待导航的正确模式如下:

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

快捷键page.mainFrame().click(selector[, options]).

page.close()
page.content()

获取页面的完整HTML内容,包括文档类型。

page.cookies(...urls)

如果未指定URL,则此方法返回当前页面URL的Cookie。 如果指定了URL,则仅返回这些URL的Cookie。

page.coverage
page.deleteCookie(...cookies)
page.emulate(options)
  • options <Object>
    • viewport <Object>
      • width <number> 页面宽度(像素)。
      • height <number> 页面高度(按像素)。
      • deviceScaleFactor <number> 指定设备缩放因子(可以认为是dpr)。默认为 1.
      • isMobile <boolean>是否考虑了meta viewport标签。 默认为 false.
      • hasTouch<boolean> 指定视口是否支持触摸事件. 默认为 false
      • isLandscape <boolean> 指定视口是否处于横向模式. 默认为 false.
    • userAgent <string>
  • returns: <Promise>

仿真给定的设备指标和用户代理. 此方法是调用两种方法的捷径:

为了辅助仿真,puppeteer提供了可以通过require('puppeteer / DeviceDescriptors')命令获得的设备描述符列表。 下面是一个在puppeteer中模拟iPhone 6的例子:

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

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

源代码中提供了所有可用设备的列表: DeviceDescriptors.js.

page.emulateMedia(mediaType)
  • mediaType <?string> 更改页面的CSS媒体类型. 唯一允许的值是 'screen', 'print'null. 传递null将禁用媒体仿真。
  • returns: <Promise>
page.evaluate(pageFunction, ...args)

如果传递给page.evaluate的函数返回一个Promise,那么page.evaluate将等待承诺解析并返回它的值。

如果传递给page.evaluate的函数返回一个非Serializable值,那么page.evaluate将解析为undefined

传递参数给 pageFunction:

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

一个字符串也可以传入而不是一个函数:

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

ElementHandle实例可以作为参数传递给page.evaluate

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

快捷键 page.mainFrame().evaluate(pageFunction, ...args).

page.evaluateHandle(pageFunction, ...args)

page.evaluatepage.evaluateHandle唯一的区别在于page.evaluateHandle返回页内对象(JSHandle)。

如果传递给page.evaluateHandle的函数返回一个Promise,那么page.evaluateHandle将等待承诺解析并返回它的值。

一个字符串也可以传入而不是一个函数:

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

JSHandle实例可以作为参数传递给page.evaluateHandle

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

快捷键page.mainFrame().executionContext().evaluateHandle(pageFunction, ...args).

page.evaluateOnNewDocument(pageFunction, ...args)

添加一个将在下列情况之一中调用的函数:

  • 每当页面被导航时
  • 每当子框架被附加或导航时。在这种情况下,函数在新连接的帧的上下文中调用

该函数在创建文档之后但在其任何脚本运行之前被调用。 这对修改JavaScript环境很有用,例如 to seed Math.random.

在加载页面之前覆盖navigator.languages属性的示例:

// preload.js

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

// In your puppeteer script, assuming the preload.js file is in same folder of our script
const preloadFile = fs.readFileSync('./preload.js', 'utf8');
await page.evaluateOnNewDocument(preloadFile);
page.exposeFunction(name, puppeteerFunction)
  • name <string> Name of the function on the window object
  • puppeteerFunction <function> Callback function which will be called in Puppeteer's context.
  • returns: <Promise>

该方法在页面的window对象上添加一个名为name的函数。 当被调用时,函数在node.js中执行puppeteerFunction,并返回一个Promise,它解析为puppeteerFunction的返回值。

如果puppeteerFunction返回一个Promise,它将被等待。

NOTE 通过page.exposeFunction安装的函数 survive navigations.

在页面中添加一个md5函数的例子:

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

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

在页面中添加一个window.readfile函数的例子:

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

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

page.focus(selector)
  • selector <string> 要聚焦的元素的selector。 如果有多个元素满足选择器,则第一个将被聚焦。
  • returns: <Promise> 当匹配selector的元素被成功聚焦时,Promise会解析。 如果没有匹配selector的元素,Promise将被拒绝。

此方法使用selector获取元素并将其聚焦。 如果没有与selector匹配的元素,则该方法将引发错误。

快捷键 page.mainFrame().focus(selector).

page.frames()
  • returns: <Array<Frame>> 连接到页面的所有框架的数组。
page.goBack(options)
  • options <Object> 导航参数可能具有以下属性:
    • timeout <number> 最大导航时间,以毫秒为单位, 默认为30秒, 通过0来禁用超时。 默认值可以通过使用 page.setDefaultNavigationTimeout(timeout) method.
    • waitUntil <string|Array<string>> 何时考虑导航成功, 默认为 load. 给定一组事件字符串,导航在所有事件被触发后被认为是成功的。事件也可以是:
      • load - 考虑在load事件被触发时导航结束。
      • domcontentloaded - 考虑在DOMContentLoaded事件被触发时导航完成。
      • networkidle0 - 当网络连接数量不超过0个网络连接的时间至少为500毫秒时,请考虑导航完成。
      • networkidle2 - 当网络连接数不超过2个时,导航至少需要500秒。
  • returns: <Promise<?Response>> Promise解决主要资源响应。 在多重重定向的情况下,导航将通过最后重定向的响应来解决。如果不能返回,则解析为null

导航到历史记录中的上一页。

page.goForward(options)
  • options <Object> 导航参数可能具有以下属性:
    • timeout <number> 最大导航时间以毫秒为单位,默认为30秒,通过0来禁用超时。 可以使用page.setDefaultNavigationTimeout(timeout)方法更改默认值。
    • waitUntil <string|Array<string>> 何时考虑导航成功,默认为load。 给定一组事件字符串,导航在所有事件被触发后被认为是成功的。Events can be either:
      • load - 考虑在load事件被触发时导航结束。
      • domcontentloaded - 考虑在DOMContentLoaded事件被触发时导航完成。
      • networkidle0 - 当网络连接数量不超过0个网络连接的时间至少为500毫秒时,请考虑导航完成。
      • networkidle2 - 当网络连接数不超过2个时,导航至少需要500秒。
  • returns: <Promise<?Response>> 承诺解决主要资源响应。 在多重重定向的情况下,导航将通过最后重定向的响应来解决。如果

导航到历史中的下一页。

page.goto(url, options)
  • url <string> 将页面导航到的URL。, e.g. https://.
  • options <Object> 导航参数可能具有以下属性:
    • timeout <number> 最大导航时间,以毫秒为单位, 默认为30秒, 通过0来禁用超时. 默认值可以通过使用 page.setDefaultNavigationTimeout(timeout) 方法.
    • waitUntil <string|Array<string>> 何时考虑导航成功, 默认为 load. 给定一组事件字符串,导航在所有事件被触发后被认为是成功的. Events can be either:
      • load - 考虑在load事件被触发时导航结束。
      • domcontentloaded - 考虑在DOMContentLoaded事件被触发时导航完成。
      • networkidle0 - 当网络连接数量不超过0个网络连接的时间至少为500毫秒时,请考虑导航完成。
      • networkidle2 - consider navigation to be finished when there are no more than 2 network connections for at least 500 ms.
  • returns: <Promise<?Response>> 承诺解决主要资源响应。在多重重定向的情况下,导航将通过最后重定向的响应来解决。

如果出现以下情况,page.goto将会抛出一个错误:

  • 存在SSL错误(例如,在自签名证书的情况下)。
  • 目标网址无效。
  • 在导航过程中会超出timeout
  • 主资源加载失败。

NOTE page.goto 或者抛出或返回主资源响应。 唯一的例外是导航到about:blank,这将成功并返回 null.

NOTE 无头模式不支持导航到PDF文档。 See the upstream issue.

page.hover(selector)
  • selector <string> selector搜索要悬停的元素。如果有多个元素满足选择器,则第一个元素将被徘徊。
  • returns: <Promise> 当匹配selector的元素成功执行时,Promise会解析。 如果没有匹配selector的元素,Promise将被拒绝。

此方法使用selector获取元素,如果需要将其滚动到视图中,然后使用page.mouse将鼠标悬停在元素的中心。 如果没有与selector匹配的元素,则该方法将引发错误。

快捷键 page.mainFrame().hover(selector).

page.keyboard
page.mainFrame()
  • returns: <Frame> 返回页面的主框架。

页面保证具有在导航过程中持续存在的主框架。

page.metrics()
  • returns: <Promise<Object>> 包含指标作为键/值对的对象。
    • Timestamp <number> 采集指标样本时的时间戳。
    • Documents <number> 页面中的文档数量。
    • Frames <number> 页面中的帧数。
    • JSEventListeners <number> 页面中的事件数量。
    • Nodes <number> 页面中DOM节点的数量。
    • LayoutCount <number> 完整或部分页面布局的总数。
    • RecalcStyleCount <number> 总页数风格重新计算。
    • LayoutDuration <number> 所有页面布局的合并持续时间。
    • RecalcStyleDuration <number> 所有页面样式重新计算的组合持续时间。
    • ScriptDuration <number> JavaScript执行的组合持续时间。
    • TaskDuration <number> 浏览器执行的所有任务的合并持续时间。
    • JSHeapUsedSize <number> 使用JavaScript堆大小。
    • JSHeapTotalSize <number> 总的JavaScript堆大小。

NOTE 所有时间戳都是单调时间:从过去的任意点开始,以秒为单位的单调递增时间。

page.mouse
page.pdf(options)
  • options <Object> 选项对象可能具有以下属性:
    • path <string> 保存PDF的文件路径。 如果path是相对路径,则相对于current working directory. 如果未提供路径,则PDF将不会保存到磁盘。
    • scale <number> 网页渲染的比例。 默认为 1.
    • displayHeaderFooter <boolean> 显示页眉和页脚。 默认为 false.
    • headerTemplate <string> 打印头的HTML模板。 应该是有效的HTML标记,以下类用于向它们中注入打印值:
      • date 格式化的打印日期
      • title 文件名
      • url 文件位置
      • pageNumber 当前页码
      • totalPages 文档中的总页数
    • footerTemplate <string> 打印页脚的HTML模板。 应该使用与headerTemplate相同的格式。
    • printBackground <boolean> 打印背景图形。 默认为 false.
    • landscape <boolean> 纸张方向。 默认为 false.
    • pageRanges <string> 要打印的纸张范围, '1-5, 8, 11-13'. 默认为空字符串,这意味着打印所有页面。
    • format <string> 纸张格式。 如果设置,则优先于width or height选项。 默认为 'Letter'.
    • width <string> 纸张宽度,接受以单位标记的值.
    • height <string> 纸张高度,接受标有单位的值.
    • margin <Object> 纸张边距,默认为无.
      • top <string> 上边距,接受以单位标记的值.
      • right <string> 右边距,接受标有单位的值.
      • bottom <string> 底部边距,接受标有单位的值.
      • left <string> 左边距,接受标有单位的值.
  • returns: <Promise<Buffer>> 承诺用PDF缓冲区解决.

NOTE 生成PDF目前仅在Chrome无头版中受支持.

page.pdf() 使用print css媒体生成页面的pdf。 用screen媒体生成pdf, 调用 page.emulateMedia('screen') 在之前 调用 page.pdf():

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

The width, height, and margin 选项接受标有单位的值。 未标记的值被视为像素。

A few examples:

  • page.pdf({width: 100}) - 宽度设置为100像素的打印
  • page.pdf({width: '100px'}) -宽度设置为100像素的打印
  • page.pdf({width: '10cm'}) - 打印宽度设置为10厘米。

所有可能的单位是:

  • px - 像素
  • in - 英寸
  • cm - 厘米
  • mm - 毫米

format选项是:

  • Letter: 8.5in x 11in
  • Legal: 8.5in x 14in
  • Tabloid: 11in x 17in
  • Ledger: 17in x 11in
  • A0: 33.1in x 46.8in
  • A1: 23.4in x 33.1in
  • A2: 16.5in x 23.4in
  • A3: 11.7in x 16.5in
  • A4: 8.27in x 11.7in
  • A5: 5.83in x 8.27in
  • A6: 4.13in x 5.83in
page.queryObjects(prototypeHandle)
  • prototypeHandle <JSHandle> 对象原型的句柄。
  • returns: <Promise<JSHandle>> Promise解决了这个原型的一个对象数组的句柄。

该方法迭代JavaScript堆,并找到具有给定原型的所有对象。

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

快捷键 page.mainFrame().executionContext().queryObjects(prototypeHandle).

page.reload(options)
  • options <Object> 导航参数可能具有以下属性:
    • timeout <number> 最大导航时间以毫秒为单位,默认为30秒,通过0来禁用超时。 默认值可以通过使用page.setDefaultNavigationTimeout(timeout) 方法.
    • waitUntil <string|Array<string>> 何时考虑导航成功, 默认为 load. 给定一组事件字符串, 在所有事件被解雇后,导航被认为是成功的。 Events can be either:
      • load - 考虑在load事件被触发时导航结束。
      • domcontentloaded - 考虑导航完成 当DOMContentLoaded事件被触发时。
      • networkidle0 - 当网络连接数量不超过0个网络连接的时间至少为500毫秒时,请考虑导航完成。
      • networkidle2 - 当网络连接数不超过2个时,导航至少需要500秒。
  • returns: <Promise<Response>> 承诺解决主要资源响应。在多重重定向的情况下,导航将通过最后重定向的响应来解决。
page.screenshot([options])
  • options <Object> 选项对象可能具有以下属性:
    • path <string> 保存图像的文件路径。如果path是一个相对路径,那么它相对于它被解析 current working directory. 如果没有提供路径,图像将不会保存到磁盘。
    • type <string> 指定截图类型,可以是jpegpng。 默认为 'png'.
    • quality <number> 图像质量介于0-100之间。 Not applicable to png images.
    • fullPage <boolean> When true, 截取完整的可滚动页面. 默认为 false.
    • clip <Object> 指定页面剪切区域的对象. 应该有以下字段:
      • x <number> 剪辑区域左上角的x坐标
      • y <number> 剪辑区域左上角的y坐标
      • width <number> 剪辑区域的宽度
      • height <number> 剪辑区域的高度
    • omitBackground <boolean> 隐藏默认的白色背景并允许以透明度捕捉屏幕截图。默认为 false.
  • returns: <Promise<Buffer>> 承诺解决与捕获的截图缓冲
page.select(selector, ...values)
  • selector <string> 一个selector查询页面
  • ...values <...string> 要选择的选项值。如果<select>具有multiple属性,则考虑所有值,否则只考虑第一个值。
  • returns: <Promise<Array<string>>> 返回已成功选择的选项值数组。

一旦选择了所有提供的选项,触发changeinput事件。 如果没有匹配selector<select>元素,该方法会抛出一个错误。

page.select('select#colors', 'blue'); // single selection
page.select('select#colors', 'red', 'green', 'blue'); // multiple selections

快捷键 page.mainFrame().select()

page.setCacheEnabled(enabled)

基于启用状态,切换忽略每个请求的缓存。默认情况下,缓存已启用。

page.setContent(html)
page.setCookie(...cookies)
page.setDefaultNavigationTimeout(timeout)
  • timeout <number> 最大导航时间,以毫秒为单位

此设置将为以下方法更改30秒的默认最大导航时间:

page.setExtraHTTPHeaders(headers)
  • headers <Object> 包含额外的http标头的对象将随每个请求一起发送。 所有标头值必须是字符串。
  • returns: <Promise>

额外的HTTP标题将随着页面启动的每个请求一起发送。

NOTE page.setExtraHTTPHeaders 不保证传出请求中的标题顺序。

page.setJavaScriptEnabled(enabled)
  • enabled <boolean> 是否在页面上启用JavaScript。
  • returns: <Promise>

NOTE 更改此值不会影响已经运行的脚本。 它将对下一个导航.

page.setOfflineMode(enabled)
  • enabled <boolean> 当true时,为页面启用离线模式。
  • returns: <Promise>
page.setRequestInterception(value)

激活请求拦截功能 request.abort, request.continuerequest.respond 方法.

一个简单的请求拦截器的例子,它会中止所有的图像请求:

const puppeteer = require('puppeteer');

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

NOTE 启用请求拦截将禁用页面缓存。

page.setUserAgent(userAgent)
  • userAgent <string> 在此页面中使用的特定用户代理
  • returns: <Promise> Promise在用户代理被设置时解决。
page.setViewport(viewport)
  • viewport <Object>
    • width <number> 页面宽度(像素)。
    • height <number> 页面高度(按像素)。
    • deviceScaleFactor <number> 指定设备比例因子 (可以被认为是dpr). 默认为 1.
    • isMobile <boolean> 是否考虑了meta viewport标签。 默认为 false.
    • hasTouch<boolean> 指定视口是否支持触摸事件。 默认为 false
    • isLandscape <boolean>指定视口是否处于横向模式。 默认为 false.
  • returns: <Promise>

NOTE 在某些情况下, 设置视口将重新加载页面,以设置isMobilehasTouch属性。

对于单个浏览器中的多个页面,每个页面都可以有自己的视口大小。

page.tap(selector)
  • selector <string>selector搜索要点击的元素。 如果有多个元素满足选择器,则会轻击第一个元素。
  • returns: <Promise>

这个方法用selector获取一个元素, 如果需要的话,将其滚动到视图中, 然后使用page.touchscreen点击元素的中心。 如果没有元素匹配 selector, 该方法会引发错误。

快捷键 page.mainFrame().tap(selector).

page.target()
  • returns: <Target> 这个页面的目标是从中创建的。
page.title()

Shortcut for page.mainFrame().title().

page.touchscreen
page.tracing
page.type(selector, text[, options])
  • selector <string> 要键入的元素的selector。 如果有多个元素满足选择器,则会使用第一个元素。
  • text <string> 要输入焦点元素的文本。
  • options <Object>
    • delay <number> 按键之间的等待时间,以毫秒为单位。默认为 0.
  • returns: <Promise>

发送一个 keydown, keypress/input, and keyup 事件为文本中的每个字符。

按一个特殊的键, 喜欢 Control or 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.url()

这是一个捷径 page.mainFrame().url()

page.viewport()
  • returns: <Object>
    • width <number> 页面宽度(像素)。
    • height <number> 页面高度(按像素)。
    • deviceScaleFactor <number> 指定设备比例因子 (can be though of as dpr). 默认为 1.
    • isMobile <boolean> 是否考虑了meta viewport标签。 默认为 false.
    • hasTouch<boolean> 指定视口是否支持触摸事件. 默认为 false
    • isLandscape <boolean> 指定视口是否处于横向模式. 默认为 false.
page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])

该方法的行为与第一个参数的类型有所不同:

  • 如果 selectorOrFunctionOrTimeout 是一个 string, 那么第一个参数被视为selectorxpath,具体取决于它是否以'//'开头,并且该方法是一个快捷方式 page.waitForSelector or page.waitForXPath
  • 如果 selectorOrFunctionOrTimeout 是一个 function, 那么第一个参数被当作一个谓词来等待,并且该方法是一个快捷方式 page.waitForFunction().
  • 如果selectorOrFunctionOrTimeout 是一个 number, 那么第一个参数将被视为以毫秒为单位的超时,并且该方法返回一个在超时后解析的Promise
  • 否则,会引发异常

Shortcut for page.mainFrame().waitFor(selectorOrFunctionOrTimeout[, options[, ...args]]).

page.waitForFunction(pageFunction[, options[, ...args]])
  • pageFunction <function|string> 在浏览器上下文中执行函数
  • options <Object> 可选的等待参数
    • polling <string|number> 间隔时间 pageFunction 被执行, 默认为 raf. 如果 polling 是一个数字,那么它被视为一个以毫秒为单位执行函数的时间间隔。 如果polling是一个字符串,那么它可以是以下值之一:
      • raf - 在requestAnimationFrame回调中不断执行pageFunction。这是适合观察造型变化的最紧密轮询模式。
      • mutation - 在每个DOM变异上执行pageFunction
    • timeout <number> 最长等待时间,以毫秒为单位。 默认为 30000 (30 seconds).
  • ...args <...Serializable|JSHandle> 参数传递给 pageFunction
  • returns: <Promise<JSHandle>> Promise什么时候解决 pageFunction 返回一个真值。 它解决了真值的JSHandle。

The waitForFunction 可用于观察视口大小更改:

const puppeteer = require('puppeteer');

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

快捷键 page.mainFrame().waitForFunction(pageFunction[, options[, ...args]]).

page.waitForNavigation(options)
  • options <Object> 导航参数可能具有以下属性:
    • timeout <number> 最大导航时间,以毫秒为单位, 默认为30秒, 通过0来禁用超时. 默认值可以通过使用 page.setDefaultNavigationTimeout(timeout) 方法.
    • waitUntil <string|Array<string>> 何时考虑导航成功, 默认为 load. 给定一组事件字符串,导航在所有事件被触发后被认为是成功的。 Events can be either:
      • load - 考虑导航完成 when the load event is fired.
      • domcontentloaded -考虑导航完成 when the DOMContentLoaded event is fired.
      • networkidle0 - 考虑导航完成 当网络连接数不超过0时,至少为500ms。
      • networkidle2 - 考虑导航完成 当不超过2个网络连接至少为500 ms。
  • returns: <Promise<Response>> 承诺解决主要资源响应。 在多重重定向的情况下,导航将通过最后重定向的响应来解决。
page.waitForSelector(selector[, options])
  • selector <string> 要等待的元素的selector
  • options <Object> 可选的等待参数
    • visible <boolean> 等待元素出现在DOM中并可见, i.e. 没有display:nonevisibility:hidden CSS属性。 默认为 false.
    • hidden <boolean> 等待元素在DOM中找不到或被隐藏,即具有display:nonevisibility:hidden CSS属性。 默认为 false.
    • timeout <number> 最长等待时间,以毫秒为单位。默认为 30000 (30 seconds).
  • returns: <Promise<ElementHandle>> 当选择器字符串指定的元素被添加到DOM时,Promise将被解析。

等待selector出现在页面中。 如果在调用方法时selector已经存在, 该方法将立即返回。 如果选择器在timeout等待毫秒后没有出现,则该函数将抛出。 此方法适用于各种导航:

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();
});

Shortcut for page.mainFrame().waitForSelector(selector[, options]).

page.waitForXPath(xpath[, options])
  • xpath <string> 要等待的元素的xpath
  • options <Object> 可选的等待参数
    • visible <boolean> 等待元素出现在DOM中并可见, i.e. 没有display:nonevisibility:hidden CSS属性。 默认为 false.
    • hidden <boolean> 等待元素在DOM中找不到或者被隐藏, i.e. 有display:nonevisibility:hidden CSS属性。 默认为 false.
    • timeout <number> 最长等待时间,以毫秒为单位。 默认为 30000 (30 seconds).
  • returns: <Promise<ElementHandle>> Promise将在xpath字符串指定的元素添加到DOM时解析。

等待xpath出现在页面中。如果在调用该方法的时候xpath已经存在,该方法将立即返回。 如果xpath在timeout等待毫秒后没有出现,则该函数将抛出。

此方法适用于各种导航:

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]).

class: Keyboard

键盘提供了一个管理虚拟键盘的api。 高级别的API是 keyboard.type, 它会采用原始​​字符并在页面上生成适当的keydown,按键/输入和键盘事件。

为了更好的控制,您可以使用keyboard.downkeyboard.up,而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');
// Result text will end up saying 'Hello!'

An example of pressing A

await page.keyboard.down('Shift');
await page.keyboard.press('KeyA');
await page.keyboard.up('Shift');

NOTE 在MacOS上,键盘快捷键就像 ⌘ A -> 选择全部不起作用。 看到 #1313

keyboard.down(key[, options])
  • key <string> 按键的名称, 如 ArrowLeft. 请参阅USKeyboardLayout以获取所有键名称的列表。
  • options <Object>
    • text <string> 如果指定,则使用此文本生成输入事件。
  • returns: <Promise>

分派keydown事件。

如果key是一个单独的字符,除了Shift之外没有修饰键被按下, 一个keypress /input事件也会产生。 可以指定text选项来强制生成输入事件。

如果key是一个修饰键,ShiftMetaControlAlt,随着这个修饰符的激活,随后的按键将被发送。 释放修饰键, use keyboard.up.

按键一次后, 随后 调用 keyboard.down 将有 repeat 设置为true. 要释放密钥,请使用 keyboard.up.

NOTE 修饰键DO影响 keyboard.down. 按住Shift键将以大写形式输入文本。

keyboard.press(key[, options])
  • key <string> 按键的名称, 如 ArrowLeft. 请参阅USKeyboardLayout以获取所有键名称的列表。
  • options <Object>
    • text <string> 如果指定,则使用此文本生成输入事件。
    • delay <number> 等待之间的时间 keydownkeyup 以毫秒为单位. 默认为 0.
  • returns: <Promise>

如果key是一个单独的字符,除了Shift之外没有修饰键被按下, 一个keypress /input事件也会产生。 可以指定text选项来强制生成输入事件。

NOTE 修改键效果 elementHandle.press. 按住Shift键将以大写形式输入文本。

快捷键 keyboard.downkeyboard.up.

keyboard.sendCharacter(char)

分派keypressinput事件。 这不会发送keydownkeyup事件。

page.keyboard.sendCharacter('嗨');

NOTE 修饰键不起作用 keyboard.sendCharacter. 按住Shift键不会输入大写字母。

keyboard.type(text, options)
  • text <string> 要输入焦点元素的文本。
  • options <Object>
    • delay <number> 按键之间的等待时间,以毫秒为单位。 默认为 0.
  • returns: <Promise>

发送一个 keydown, keypress/input, 和 keyup 事件为文本中的每个字符。

按一个特殊的键, 喜欢 Control or ArrowDown, 使用 keyboard.press.

page.keyboard.type('Hello'); // Types instantly
page.keyboard.type('World', {delay: 100}); // Types slower, like a user

NOTE 修饰键不起作用 keyboard.type. 按住Shift键不会输入大写字母。

keyboard.up(key)

分派一个keyup事件。

class: Mouse

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

快捷键 mouse.move, mouse.down and mouse.up.

mouse.down([options])

Dispatches 一个mousedown事件。

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

Dispatches 一个mousemove事件。

mouse.up([options])

Dispatches 一个mouseup事件。

class: Touchscreen

touchscreen.tap(x, y)

Dispatches touchstarttouchend事件。

class: Tracing

您可以使用 tracing.starttracing.stop 创建一个可以在Chrome DevTools中打开的跟踪文件 or timeline viewer.

await page.tracing.start({path: 'trace.json'});
await page.goto('https://www.google.com');
await page.tracing.stop();
tracing.start(options)
  • options <Object>
    • path <string> 将跟踪文件写入的路径. required
    • screenshots <boolean> 捕获跟踪中的屏幕截图。
    • categories <Array<string>> 指定要使用的自定义类别而不是默认值。
  • returns: <Promise>

每个浏览器一次只能激活一条跟踪。

tracing.stop()

class: Dialog

Dialog 对象是通过页面分派的 'dialog' 事件.

使用Dialog类的一个例子:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  page.on('dialog', async dialog => {
    console.log(dialog.message());
    await dialog.dismiss();
    await browser.close();
  });
  page.evaluate(() => alert('1'));
});
dialog.accept([promptText])
  • promptText <string> 提示中输入的文本。 如果对话框的type不提示,不会产生任何影响。
  • returns: <Promise> 当对话已被接受时,承诺会解决。
dialog.defaultValue()
  • returns: <string> 如果对话框出现提示,则返回默认提示值。否则,返回空字符串。
dialog.dismiss()
  • returns: <Promise> 当对话被dismissed时,承诺会resolves。
dialog.message()
  • returns: <string> 显示在对话框中的消息。
dialog.type()
  • returns: <string> 对话框的类型,可以是其中之一 alert, beforeunload, confirm or prompt.

class: ConsoleMessage

ConsoleMessage 对象是通过页面分派的 'console' 事件.

consoleMessage.args()
consoleMessage.text()
consoleMessage.type()

以下值之一: 'log', 'debug', 'info', 'error', 'warning', 'dir', 'dirxml', 'table', 'trace', 'clear', 'startGroup', 'startGroupCollapsed', 'endGroup', 'assert', 'profile', 'profileEnd', 'count', 'timeEnd'.

class: Frame

在每一个时间点,页面都会通过该页面公开当前frame树 page.mainFrame()frame.childFrames() 方法.

Frame 对象的生命周期由三个事件控制,分派在页面对象上:

  • 'frameattached' - 当框架连接到页面时触发。 一个框架只能附加到该页面一次。
  • 'framenavigated' - 当框架提交导航到不同的URL时触发。
  • 'framedetached' - 当框架从页面分离时触发。一个框架只能从页面上分离一次。

转储frame树的一个例​​子:

const puppeteer = require('puppeteer');

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

  function dumpFrameTree(frame, indent) {
    console.log(indent + frame.url());
    for (let child of frame.childFrames())
      dumpFrameTree(child, indent + '  ');
  }
});
frame.$(selector)
  • selector <string> 选择器查询页面
  • returns: <Promise<?ElementHandle>> Promise将resolves解析为指向Frame元素的ElementHandle。

该方法查询选择器的frame。 如果框架内没有这样的元素,该方法将解析为null

frame.$$(selector)

该方法在框架内运行document.querySelectorAll。 如果没有元素匹配选择器,则返回值将解析为[]

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

此方法运行 document.querySelectorAll 在框架内并将其作为第一个参数传递给 pageFunction.

如果 pageFunction 返回一个Promise, 然后 frame.$$eval 将等待承诺解决并返回其价值。

例子:

const divsCounts = await frame.$$eval('div', divs => divs.length);
frame.$eval(selector, pageFunction[, ...args])

这个方法在框架内运行document.querySelector并将它作为第一个参数传递给pageFunction。如果没有与selector匹配的元素,则该方法将引发错误。

如果pageFunction返回一个Promise,那么frame.$eval将等待承诺解析并返回它的值。

Examples:

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

该方法评估XPath表达式。

frame.addScriptTag(options)
  • options <Object>
    • url <string> 要添加的脚本的URL。
    • path <string> 将JavaScript文件注入frame的路径。如果path是一个相对路径,那么它相对于它被解析 current working directory.
    • content <string> 将原始JavaScript内容注入到框架中。
  • returns: <Promise<ElementHandle>> 当脚本的onload触发或者脚本内容被注入到框架中时,它解析为添加的标记。

将'<script>`标签添加到具有所需网址或内容的页面中。

frame.addStyleTag(options)
  • options <Object>
    • url <string> <link>标签的URL。
    • path <string> 将CSS文件注入frame的路径。 如果path是一个相对路径,那么它相对于它被解析 current working directory.
    • content <string> 将原始CSS内容注入frame。
  • returns: <Promise<ElementHandle>> 当样式表的onload被触发时或CSS内容被注入到框架中时,它解析为添加的标签。

添加一个 <link rel="stylesheet"> 使用所需的url或a标记到页面中 <style type="text/css"> 标记内容。

frame.childFrames()
frame.click(selector[, options])
  • selector <string> selector搜索要单击的元素。如果有多个元素满足选择器,则会首先点击。
  • options <Object>
    • button <string> left, right, or middle, 默认为 left.
    • clickCount <number> 默认为 1. See UIEvent.detail.
    • delay <number> 等待时间 mousedownmouseup之间以毫秒为单位。 默认为 0.
  • returns: <Promise> 当这个元素匹配时,Promise会解析它 selector 被成功点击. 如果没有匹配selector的元素,Promise将被拒绝。

此方法使用selector获取元素,如果需要将其滚动到视图中,然后使用page.mouse单击元素的中心。 如果没有与selector匹配的元素,则该方法将引发错误。

请记住,如果click()触发一个导航事件,并且有一个单独的page.waitForNavigation()承诺被解析,那么最终可能会导致竞争条件,从而产生意想不到的结果。 The correct pattern for click and wait for navigation is the following:

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

获取框架的完整HTML内容,包括文档类型。

frame.evaluate(pageFunction, ...args)

如果函数传递给 frame.evaluate 返回一个Promise, 那么frame.evaluate将等待Promise resolve并返回它的值。

如果函数传递给 frame.evaluate 返回一个非Serializable值, 然后 frame.evaluate resolves to undefined.

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

一个字符串也可以被传入而不是一个函数。

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

ElementHandle 实例可以作为参数传递给 frame.evaluate:

const bodyHandle = await frame.$('body');
const html = await frame.evaluate(body => body.innerHTML, bodyHandle);
await bodyHandle.dispose();
frame.evaluateHandle(pageFunction, ...args)

frame.evaluate和frame.evaluateHandle唯一的区别在于frame.evaluateHandle返回页内对象(JSHandle)。

如果传递给frame.evaluateHandle的函数返回一个Promise,那么frame.evaluateHandle将等待Promise resovle并返回它的值。

const aWindowHandle = await frame.evaluateHandle(() => Promise.resolve(window));
aWindowHandle; // Handle for the window object.

一个字符串也可以被传入而不是一个函数。

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

JSHandle实例可以作为参数传递给frame.evaluateHandle

const aHandle = await frame.evaluateHandle(() => document.body);
const resultHandle = await frame.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue());
await resultHandle.dispose();
frame.executionContext()
frame.focus(selector)
  • selector <string> 要聚焦的元素的selector。 如果有多个元素满足选择器,则第一个将被聚焦。
  • returns: <Promise> 当匹配selector的元素被成功聚焦时,Promise会解析。 如果没有匹配selector的元素,承诺将被拒绝。

此方法使用selector获取元素并将其聚焦。 如果没有与selector匹配的元素,则该方法将引发错误。

frame.hover(selector)
  • selector <string> selector搜索要悬停的元素。 如果有多个元素满足选择器,则第一个元素将被徘徊。
  • returns: <Promise> 当匹配selector的元素成功执行时,Promise会解析。 如果没有匹配selector的元素,Promise将被拒绝。

此方法使用selector获取元素,如果需要将其滚动到视图中,然后使用page.mouse将鼠标悬停在元素的中心。 如果没有与selector匹配的元素,则该方法将引发错误。

frame.isDetached()

如果该框架已被分离,则返回true;否则返回false

frame.name()

返回标签中指定的框架的名称属性。

如果名称为空,则返回id属性。

NOTE 该值在创建框架时计算一次,如果稍后更改属性,则不会更新。

frame.parentFrame()
  • returns: <?Frame> 返回父框架,如果有的话. 分离的 frame 和主frame返回 null.
frame.select(selector, ...values)
  • selector <string> 一个selector来查询frame
  • ...values <...string> 要选择的选项值。 如果<select>具有multiple属性,则考虑所有值,否则只考虑第一个值。
  • returns: <Promise<Array<string>>> 返回已成功选择的选项值数组。

一旦选择了所有提供的选项,触发changeinput事件。 如果没有匹配selector<select>元素,该方法会抛出一个错误。

frame.select('select#colors', 'blue'); // single selection
frame.select('select#colors', 'red', 'green', 'blue'); // multiple selections
frame.setContent(html)
frame.tap(selector)
  • selector <string> selector搜索要点击的元素。如果有多个元素满足选择器,则会轻击第一个元素。
  • returns: <Promise>

此方法使用获取元素 selector, 如果需要将其滚动到视图中,然后使用page.touchscreen点击元素的中心。 如果没有与selector匹配的元素,则该方法将引发错误。

frame.title()
frame.type(selector, text[, options])
  • selector <string> 要键入的元素的selector。 如果有多个元素满足选择器,则会使用第一个元素。
  • text <string> 要输入焦点元素的文本。
  • options <Object>
    • delay <number> 按键之间的等待时间,以毫秒为单位. 默认为 0.
  • returns: <Promise>

发送一个 keydown, keypress/input, and keyup 事件为文本中的每个字符。

按一个特殊的键, like Control or ArrowDown, use keyboard.press.

frame.type('#mytextarea', 'Hello'); // Types instantly
frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
frame.url()

返回框架的网址。

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

该方法的行为与第一个参数的类型有所不同:

  • 如果selectorOrFunctionOrTimeout是一个string,那么第一个参数将被视为selectorxpath,具体取决于它是否以//开头,并且该方法是一个快捷方式 frame.waitForSelector or frame.waitForXPath
  • 如果selectorOrFunctionOrTimeout是一个function,那么第一个参数就被当作一个谓词来等待,这个方法是一个快捷方式 frame.waitForFunction().
  • 如果selectorOrFunctionOrTimeout是一个number,那么第一个参数被视为以毫秒为单位的超时,并且该方法返回一个在超时之后解析的promise
  • 否则,会引发异常
frame.waitForFunction(pageFunction[, options[, ...args]])
  • pageFunction <function|string> 在浏览器上下文中执行函数
  • options <Object> 可选的等待参数
    • polling <string|number> 执行pageFunction的时间间隔, 默认为 raf. 如果polling是一个数字,那么它将被视为执行函数的时间间隔(以毫秒为单位)。如果polling是一个字符串,那么它可以是以下值之一:
      • raf - 在requestAnimationFrame回调中不断执行pageFunction。 这是最严格的轮询模式 which is suitable to observe styling changes.
      • mutation - 在每个DOM变异上执行pageFunction
    • timeout <number> 最长等待时间,以毫秒为单位. 默认为 30000 (30 seconds).
  • ...args <...Serializable|JSHandle> 参数传递给 pageFunction
  • returns: <Promise<JSHandle>> Promise当pageFunction返回一个真值时解析。 它解决了真值的JSHandle。

waitForFunction可用于观察视口尺寸的变化:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  const watchDog = page.mainFrame().waitForFunction('window.innerWidth < 100');
  page.setViewport({width: 50, height: 50});
  await watchDog;
  await browser.close();
});
frame.waitForSelector(selector[, options])
  • selector <string> 要等待的元素的selector
  • options <Object> 可选的等待参数
    • visible <boolean> 等待元素出现在DOM中并可见, i.e. 没有display:nonevisibility:hidden CSS属性。 默认为 false.
    • hidden <boolean> 等待元素不在DOM中或被隐藏, i.e. 有display:nonevisibility:hidden CSS属性。 默认为 false.
    • timeout <number> 最长等待时间,以毫秒为单位。 默认为 30000 (30 seconds).
  • returns: <Promise<ElementHandle>> 当选择器字符串指定的元素被添加到DOM时,Promise将被解析。

等待selector出现在页面中。 如果在调用该方法时selector已经存在,该方法将立即返回。 如果选择器在超时等待毫秒后没有出现,则该函数将抛出。

此方法适用于各种导航:

const puppeteer = require('puppeteer');

puppeteer.launch().then(async browser => {
  const page = await browser.newPage();
  let currentURL;
  page.mainFrame()
    .waitForSelector('img')
    .then(() => console.log('First URL with image: ' + currentURL));
  for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com'])
    await page.goto(currentURL);
  await browser.close();
});
frame.waitForXPath(xpath[, options])
  • xpath <string> 要等待的元素的xpath
  • options <Object> 可选的等待参数
    • visible <boolean> 等待元素出现在DOM中并可见, i.e. 没有display:nonevisibility:hidden CSS属性。 默认为 false.
    • hidden <boolean> 等待元素不在DOM中或被隐藏, i.e. 有display:nonevisibility:hidden CSS属性. 默认为 false.
    • timeout <number> 最长等待时间,以毫秒为单位. 默认为 30000 (30 seconds).
  • returns: <Promise<ElementHandle>> Promise将在xpath字符串指定的元素添加到DOM时解析。

等待xpath出现在页面中。 如果在调用该方法的时候xpath已经存在,该方法将立即返回。如果xpath在timeout 等待毫秒后没有出现,则该函数将抛出。

此方法适用于各种导航:

const puppeteer = require('puppeteer');

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

class: ExecutionContext

该类表示JavaScript执行的上下文。 JavaScript上下文的例子是:

  • 每个frame都有一个单独的执行上下文
  • 各种各样的 workers 有自己的contexts
executionContext.evaluate(pageFunction, ...args)

如果传递给executionContext.evaluate的函数返回一个Promise,那么executionContext.evaluate将等待承诺解析并返回它的值。

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

一个字符串也可以被传入而不是一个函数。

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

JSHandle实例可以作为参数传递给executionContext.evaluate

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

executionContext.evaluateexecutionContext.evaluateHandle唯一的区别在于executionContext.evaluateHandle返回页内对象(JSHandle)。

如果传递给executionContext.evaluateHandle的函数返回一个Promise,那么executionContext.evaluteHandle将等待承诺解析并返回其值。

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

一个字符串也可以被传入而不是一个函数。

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

JSHandle实例可以作为参数传递给executionContext.evaluateHandle

const aHandle = await context.evaluateHandle(() => document.body);
const resultHandle = await context.evaluateHandle(body => body.innerHTML, aHandle);
console.log(await resultHandle.jsonValue()); // prints body's innerHTML
await aHandle.dispose();
await resultHandle.dispose();
executionContext.frame()
  • returns: <?Frame> 与此执行上下文相关的框架。

NOTE 并非每个执行上下文都与一个框架相关联。例如,工作人员和扩展程序具有与框架无关的执行上下文。

executionContext.queryObjects(prototypeHandle)
  • prototypeHandle <JSHandle> 对象原型的句柄。
  • returns: <JSHandle> 这个原型的一个对象数组的句柄

该方法迭代JavaScript堆,并找到具有给定原型的所有对象。

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

class: JSHandle

JSHandle代表一个页面内JavaScript对象。JSHandles可以使用page.evaluateHandle方法创建。

const windowHandle = await page.evaluateHandle(() => window);
// ...

JSHandle可防止引用的JavaScript对象被垃圾收集,除非句柄disposed。当原始框架被导航或父上下文被破坏时,JSHandles自动处理。

JSHandle实例可以用作参数 page.$eval(), page.evaluate()page.evaluateHandle 方法.

jsHandle.asElement()

如果对象句柄是ElementHandle的一个实例,则返回null或对象句柄本身。

jsHandle.dispose()
  • returns: <Promise> 当对象句柄被成功处理时,该Promise解决。

jsHandle.dispose方法停止引用元素句柄。

jsHandle.executionContext()

返回句柄所属的执行上下文。

jsHandle.getProperties()

该方法返回一个包含属性名称作为键的映射和属性值的JSHandle实例。

const handle = await page.evaluateHandle(() => ({window, document}));
const properties = await handle.getProperties();
const windowHandle = properties.get('window');
const documentHandle = properties.get('document');
await handle.dispose();
jsHandle.getProperty(propertyName)

从引用的对象中获取单个属性。

jsHandle.jsonValue()

返回对象的JSON表示。 如果对象有 a toJSON 功能, 它不会被调用

NOTE 如果引用的对象不可串行化,该方法将返回一个空的JSON对象。 如果对象具有循环引用,则会引发错误。

class: ElementHandle

NOTE Class ElementHandle extends JSHandle.

ElementHandle表示一个页内DOM元素。 ElementHandles可以使用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();
  // ...
});

除非句柄disposed,否则ElementHandle会阻止垃圾收集中的DOM元素。 元素句柄在其原始frame被导航时自动处理。

ElementHandle实例可以用作参数 page.$eval()page.evaluate() 方法.

elementHandle.$(selector)

该方法在页面内运行element.querySelector。 如果没有元素匹配选择器,则返回值解析为null

elementHandle.$$(selector)

该方法在页面内运行element.querySelectorAll。如果没有元素匹配选择器,则返回值将解析为[]

elementHandle.$x(expression)

该方法评估相对于elementHandle的XPath表达式。 如果没有这样的元素,该方法将解析为null

elementHandle.asElement()
elementHandle.boundingBox()
  • returns: <Promise<?Object>>
    • x <number> 元素的x坐标(以像素为单位)。
    • y <number> 元素的y坐标以像素为单位。
    • width <number> 元素的宽度以像素为单位。
    • height <number> 元素的高度以像素为单位。

此方法返回元素的边界框(相对于主框架), 如果元素不可见,则返回null

elementHandle.click([options])
  • options <Object>
    • button <string> left, right, or middle, 默认为 left.
    • clickCount <number> 默认为 1. See UIEvent.detail.
    • delay <number> 在毫秒内在mousedownmouseup之间等待的时间。 默认为 0.
  • returns: <Promise> Promise 当元素被成功地点击时,它将被解析. 如果该元素与DOM分离,Promise将被拒绝。

如果需要,此方法将元素滚动到视图中, 然后使用page.mouse单击元素的中心。 如果该元素从DOM中分离,则该方法将引发错误。

elementHandle.contentFrame()
  • returns: <Promise<?Frame>> 解析为引用iframe节点的元素句柄的内容框架,否则为空
elementHandle.dispose()
  • returns: <Promise> 当元素句柄成功处置时,Promise会解决这个问题。

elementHandle.dispose方法停止引用元素句柄。

elementHandle.executionContext()
elementHandle.focus()

在元素上调用focus

elementHandle.getProperties()

该方法返回一个包含属性名称作为键的映射和属性值的JSHandle实例。

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; // 持有elementHandles给document.body的所有子项
elementHandle.getProperty(propertyName)

从objectHandle中获取一个属性。

elementHandle.hover()
  • returns: <Promise> 当元素被成功地hovered时,承诺会解决.

如果需要,此方法将元素滚动到视图中, 然后使用 page.mouse 悬停在元素的中心。

elementHandle.jsonValue()

返回对象的JSON表示。 JSON是通过运行生成的 JSON.stringify 在页面中的对象和结果 JSON.parse in puppeteer.

NOTE 如果引用的对象不可串流化,该方法将抛出。

elementHandle.press(key[, options])
  • key <string> 按键的名称, 如 ArrowLeft. 请参阅USKeyboardLayout以获取所有键名称的列表。
  • options <Object>
    • text <string> 如果指定,则使用此文本生成输入事件。
    • delay <number> ``keydownkeyup`之间的等待时间,以毫秒为单位。 默认为 0.
  • returns: <Promise>

集中元素,然后使用 keyboard.downkeyboard.up.

如果key是一个单独的字符,并且除了Shift之外没有修饰键被按下,keypress /input事件也会被生成。 可以指定text选项来强制生成输入事件。

NOTE 修饰键DO会影响elementHandle.press。按住Shift键将以大写形式输入文本。

elementHandle.screenshot([options])

如果需要,此方法将元素滚动到视图中,然后使用page.screenshot截取元素的屏幕截图。 如果该元素从DOM中分离,则该方法将引发错误。

elementHandle.tap()
  • returns: <Promise> 在成功点击元素时解决该问题。 如果该元素与DOM分离,Promise将被拒绝。

如果需要,此方法将元素滚动到视图中, 然后使用touchscreen.tap点击元素的中心。 如果该元素从DOM中分离,则该方法将引发错误。

elementHandle.toString()
elementHandle.type(text[, options])
  • text <string> 要输入焦点元素的文本。
  • options <Object>
    • delay <number> 按键之间的等待时间,以毫秒为单位。 默认为 0.
  • returns: <Promise>

集中元素,然后为文本中的每个字符发送keydownkeypress /inputkeyup事件。

按一个特殊的键, 如 Control or ArrowDown, use elementHandle.press.

elementHandle.type('Hello'); // Types instantly
elementHandle.type('World', {delay: 100}); // Types slower, like a user

键入文本字段然后提交表单的示例:

const elementHandle = await page.$('input');
await elementHandle.type('some text');
await elementHandle.press('Enter');
elementHandle.uploadFile(...filePaths)

这个方法期望elementHandle指向一个 input element.

class: Request

每当页面发送请求时, 发出以下事件 by puppeteer's 页:

如果请求在某个时候失败了,那么不是'requestfinished'事件(也可能不是'response'事件), 发出'requestfailed'事件。

如果请求获得'redirect'响应, 该请求已成功完成 'requestfinished' 事件, 并向重定向的网址发送新的请求。

request.abort([errorCode])
  • errorCode <string> 可选的错误代码。 默认为 failed, 可能是下列之一:
    • aborted - 操作被中止 (由于用户的行为)
    • accessdenied - 访问除网络以外的资源的权限被拒绝
    • addressunreachable - IP地址无法访问。 这通常意味着没有路由到指定的主机或网络。
    • connectionaborted - 由于未收到发送数据的ACK,连接超时。
    • connectionclosed - 连接已关闭 (对应于TCP FIN).
    • connectionfailed - 连接尝试失败。
    • connectionrefused - 连接尝试被拒绝。
    • connectionreset - 连接重置 (对应于TCP RST).
    • internetdisconnected - 互联网连接已经丢失。
    • namenotresolved - 主机名称无法解析。
    • timedout - 操作超时。
    • failed - 发生通用故障。
  • returns: <Promise>

中止请求。 要使用它,请使用page.setRequestInterception来启用请求拦截。 如果请求拦截未启用,则立即抛出异常。

request.continue([overrides])
  • overrides <Object> 可选请求覆盖,可以是以下之一:
    • url <string> 如果设置,请求URL将被更改
    • method <string> 如果设置更改请求方法 (e.g. GET or POST)
    • postData <string> 如果设置更改请求的发布数据
    • headers <Object> 如果设置更改请求HTTP标头
  • returns: <Promise>

通过可选请求覆盖继续请求. 要使用它,请使用page.setRequestInterception来启用请求拦截。 如果请求拦截未启用,则立即抛出异常。

request.failure()
  • returns: <?Object> 描述请求失败的对象,如果有的话
    • errorText <string> 人类可读的错误消息, e.g. 'net::ERR_FAILED'.

该方法返回null,除非这个请求失败,如requestfailed事件报告的那样。

Example of logging all failed requests:

page.on('requestfailed', request => {
  console.log(request.url() + ' ' + request.failure().errorText);
});
request.frame()
  • returns: <?Frame> 一个匹配的Frame对象, 如果导航到错误页面,则为null.
request.headers()
  • returns: <Object> 具有与请求相关联的HTTP标头的对象。 所有标题名称都是小写。
request.method()
  • returns: <string> 请求的方法 (GET, POST, etc.)
request.postData()
  • returns: <string> 请求的post正文,如果有的话。
request.resourceType()

包含呈现引擎感知的请求资源类型。 ResourceType将是下列之一: document, stylesheet, image, media, font, script, texttrack, xhr, fetch, eventsource, websocket, manifest, other.

request.respond(response)
  • response <Object> 将满足此要求的响应
    • status <number> 响应状态码, 默认为 200.
    • headers <Object> 可选的响应标头
    • contentType <string> 如果设置,则等同于设置Content-Type响应标题
    • body <Buffer|string> 可选响应主体
  • returns: <Promise>

以给定的回应完成请求。 要使用它,请使用page.setRequestInterception来启用请求拦截。 如果请求拦截未启用,则会引发异常。

以404个响应完成所有请求的示例:

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

NOTE 不支持Mocking dataURL请求的响应。 为dataURL请求调用request.respond是一个noop。

request.response()
  • returns: <?Response> 匹配Response对象,如果尚未收到响应,则返回null
request.url()
  • returns: <string> 请求的URL。

class: Response

Response 类表示由页面接收的响应。

response.buffer()
  • returns: <Promise<Buffer>> 承诺解决与响应主体的缓冲区。
response.fromCache()

如果响应来自浏览器的磁盘缓存或内存缓存,则为true。

response.fromServiceWorker()

如果答复是由服务人员提供的,则为真。

response.headers()
  • returns: <Object> 具有与响应关联的HTTP标头的对象。
response.json()
  • returns: <Promise<Object>> Promise解析为响应主体的JSON表示。

如果响应主体不能通过JSON.parse解析,则此方法将抛出。

response.ok()

包含一个布尔值,说明响应是否成功(状态在200-299范围内)。

response.request()
response.securityDetails()
  • returns: <?SecurityDetails> 如果通过安全连接接收到响应,则为安全细节,否则为null
response.status()

包含响应的状态代码 (e.g., 200 for a success).

response.text()
  • returns: <Promise<string>> 承诺,它解析为响应主体的文本表示。
response.url()

包含响应的URL。

class: SecurityDetails

SecurityDetails 类表示由页面接收的响应。

securityDetails.issuer()
  • returns: <string> 具有证书颁发者名称的字符串。
securityDetails.protocol()
  • returns: <string> 带安全协议的字符串,例如。 "TLS 1.2".
securityDetails.subjectName()
  • returns: <string> 证书颁发给的主体的名称。
securityDetails.validFrom()
securityDetails.validTo()

class: Target

target.createCDPSession()

创建附加到目标的Chrome Devtools协议会话。

target.page()

如果目标不属于类型 "page", 回报 null.

target.type()

确定这是什么样的目标。 Can be "page", "service_worker", "browser" or "other".

target.url()

class: CDPSession

CDPSession 实例用于讨论原始Chrome Devtools协议:

  • 协议方法可以用来调用 session.send method.
  • 协议事件可以用来订阅 session.on 方法.

有关DevTools协议的文档可以在这里找到: DevTools Protocol Viewer.

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

从目标中分离cdpSession。 一旦分离,cdpSession对象将不会发出任何事件并且不能用于发送消息。

cdpSession.send(method[, params])

class: Coverage

Coverage收集有关页面使用的JavaScript和CSS部分的信息。

使用JavaScript和CSS覆盖获取最初执行代码的百分比的示例:

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

以一种可消耗的形式输出覆盖范围 Istanbul, see puppeteer-to-istanbul.

coverage.startCSSCoverage(options)
  • options <Object> 覆盖范围的可配置选项集
    • resetOnNavigation <boolean> 是否重置每个导航的覆盖范围。 默认为 true.
  • returns: <Promise> 承诺在开始覆盖时解决
coverage.startJSCoverage(options)
  • options <Object> 覆盖范围的可配置选项集
    • resetOnNavigation <boolean>是否重置每个导航的覆盖范围。 默认为 true.
  • returns: <Promise> 承诺在开始覆盖时解决
coverage.stopCSSCoverage()
  • returns: <Promise<Array<Object>>> 承诺解决所有样式表的覆盖率报告
    • url <string> 样式表网址
    • text <string> 样式表内容
    • ranges <Array<Object>> 所使用的StyleSheet范围。范围已排序且不重叠。
      • start <number> 包含文字的起始偏移量
      • end <number> 文本中的结尾偏移,独占

NOTE CSS Coverage不包含没有sourceURL的动态注入式样式标签。

coverage.stopJSCoverage()
  • returns: <Promise<Array<Object>>> 承诺解决所有非匿名脚本的覆盖报告数组
    • url <string> 脚本URL
    • text <string> 脚本内容
    • ranges <Array<Object>> 已执行的脚本范围。 范围已排序且不重叠。
      • start <number> 包含文字的起始偏移量
      • end <number> 文本中的结尾偏移,独占

NOTE JavaScript Coverage不包含匿名脚本。 但是,会报告带有sourceURL的脚本。

转载于:https://my.oschina.net/reamd7/blog/1634846

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值