puppeteer使用初探

477 阅读3分钟

我正在参与掘金创作者训练营第4期,点击了解活动详情,一起学习吧!

公司有个考试,考试范围包括一些常用的前端测试工具,其中就有puppeteer,平时没太用过,在这里做一下学习记录。

Puppeteer简介

Puppeteer 是Chrome官方团队维护的一个node库,提供了一组用来操纵Chrome的api, 通俗来说就是一个 headless chrome浏览器。

(Headless Chrome指在headless模式下运行谷歌浏览器,它将由Chromium和Blink渲染引擎提供的所有现代网页平台的特征都转化成了命令行。Headless浏览器是一种很好的工具,用于自动化测试和不需要可视化用户界面的服务器。2017年谷歌浏览器开发了其headless特性,并同时推出了Puppeteer。)

puppeteer实际上是通过调用Chrome DevTools开放的接口与Chrome通信,Chrome DevTools的接口很复杂,但puppeteer对其进行了封装,我们调用起来还是很方便的。

正如上文所说,headless浏览器可以用于自动化测试,借助它提供的api,我们可以很方便地实现

1) 生成网页截图/PDF
2) 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
3) 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染))
4) 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

API结构

  • Browser: 对应一个浏览器实例,一个 Browser 可以包含多个 BrowserContext
  • BrowserContext: 对应浏览器一个上下文会话,就像我们打开一个普通的 Chrome 之后又打开一个隐身模式的浏览器一样,BrowserContext 具有独立的 Session(cookie 和 cache 独立不共享),一个 BrowserContext 可以包含多个 Page
  • Page:表示一个 Tab 页面,通过 browserContext.newPage()/browser.newPage() 创建,browser.newPage() 创建页面时会使用默认的 BrowserContext,一个 Page 可以包含多个 Frame
  • Frame: 一个框架,每个页面有一个主框架(page.MainFrame()),也可以多个子框架,主要由 iframe 标签创建产生的
  • ExecutionContext: 是 javascript 的执行环境,每一个 Frame 都一个默认的 javascript 执行环境
  • ElementHandle: 对应 DOM 的一个元素节点,通过该该实例可以实现对元素的点击,填写表单等行为,我们可以通过选择器,xPath 等来获取对应的元素
  • JsHandle:对应 DOM 中的 javascript 对象,ElementHandle 继承于 JsHandle,由于我们无法直接操作 DOM 中对象,所以封装成 JsHandle 来实现相关功能
  • CDPSession:可以直接与原生的 CDP 进行通信,通过 session.send 函数直接发消息,通过 session.on 接收消息,可以实现 Puppeteer API 中没有涉及的功能
  • Coverage:获取 JavaScript 和 CSS 代码覆盖率
  • Tracing:抓取性能数据进行分析
  • Response: 页面收到的响应
  • Request: 页面发出的请求

配置及简单使用

安装

在项目中使用 Puppeteer:

npm i puppeteer
# or "yarn add puppeteer"

安装 Puppeteer 时,会下载最新版本的Chromium,以保证可以使用 API。 Note: Puppeteer 至少需要 Node v6.4.0,下面的示例使用 async / await,它们仅在 Node v7.6.0 或更高版本中被支持。

示例

公共部分

const puppeteer = require('puppeteer');
(async () => {
  // 例子代码放在在这里
})
  • 最简单的例子,打开百度并关闭
const browser = await puppeteer.launch({
  headless: false // 关闭headless模式
})
const page = await browser.newPage()
await page.goto('http://www.baidu.com/')
await browser.close()

增加截图并生成pdf

const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('http://www.baidu.com/')
await page.screenshot({path: 'baidu.png'})
await page.pdf({path: 'baidu.pdf'})
await browser.close()
  • 设置窗体尺寸
const browser = await puppeteer.launch({
  headless: false
})
const page = await browser.newPage()
// 模拟iPhone6的尺寸打开
await page.setViewport({
  width: 375,
  height: 667
})
await page.goto('https://www.trip.com/m/')