Puppeteer APIv1.11 中文版-阿里云开发者社区

开发者社区> 我是小助手> 正文

Puppeteer APIv1.11 中文版

简介: Puppeteer是一个Node库,它提供了一个高级API来通过DevTools协议控制Chromium或Chrome。 Puppeteer API是分层次的,反映了浏览器结构。
+关注继续查看
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_PROXYHTTPS_PROXYNO_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)

  • options <Object>
    • browserWSEndpoint <string> 一个浏览器websocket端点连接到。
    • ignoreHTTPSErrors <boolean> 是否在导航期间忽略HTTPS错误。 默认为 false.
    • slowMo <number> 将Puppeteer操作减少指定的毫秒数。 有用,这样你就可以看到发生了什么。
  • returns: <Promise<Browser>>

此方法将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(numbernumber)> 将用两个参数调用的函数:
    • 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>

你可以找到 webSocketDebuggerUrl 从 http://${host}:${port}/json/version. 了解更多关于 devtools protocol 和 browser 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 alertpromptconfirm 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 <stringselector搜索要单击的元素。如果有多个元素满足选择器,则会首先点击。
  • options <Object>
    • button <stringleftright, 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 <stringselector搜索要悬停的元素。如果有多个元素满足选择器,则第一个元素将被徘徊。
  • 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 widthheight, 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)

  • enabled <boolean> 设置缓存的enabled状态。
  • returns: <Promise>

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

page.setContent(html)

  • html <string> 分配给页面的HTML标记。
  • returns: <Promise>

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.abortrequest.continue 和 request.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>

发送一个 keydownkeypress/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:hiddenCSS属性。 默认为 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:hiddenCSS属性。 默认为 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> 等待之间的时间 keydown 和 keyup 以毫秒为单位. 默认为 0.
  • returns: <Promise>

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

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

快捷键 keyboard.down 和 keyboard.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>

发送一个 keydownkeypress/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.movemouse.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.start 和 tracing.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> 对话框的类型,可以是其中之一 alertbeforeunloadconfirm 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 <stringselector搜索要单击的元素。如果有多个元素满足选择器,则会首先点击。
  • options <Object>
    • button <stringleftright, 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)

  • pageFunction <function|string> 要在页面上下文中评估的函数
  • ...args <...Serializable|JSHandle> 参数传递给 pageFunction
  • returns: <Promise<JSHandle>> Promise哪些解决了返回值 pageFunction 作为页面内对象(JSHandle)

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 <stringselector搜索要悬停的元素。 如果有多个元素满足选择器,则第一个元素将被徘徊。
  • 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>>> 返回已成功选择的选项值数组。

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

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

frame.setContent(html)

  • html <string> 分配给页面的HTML标记。
  • returns: <Promise>

frame.tap(selector)

  • selector <stringselector搜索要点击的元素。如果有多个元素满足选择器,则会轻击第一个元素。
  • 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>

发送一个 keydownkeypress/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 <stringleftright, 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.down 和 keyboard.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将是下列之一: documentstylesheetimagemediafontscripttexttrackxhrfetcheventsourcewebsocketmanifestother.

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的脚本。


原文发布时间为:2018年03月14日
本文作者:雕刻零碎
本文来源:开源中国  如需转载请联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26502 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
10926 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
8739 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
12176 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
3668 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
21654 0
+关注
我是小助手
云栖直播
384
文章
6
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载