Puppeteer 简介
是什么
Puppeteer 是一个Chrome官方团队提供的node库,它可以通过 Puppeteer 的提供的 API 直接控制 Chrome 或 Chromiun。
可以做什么
1) 生成网页截图或者 PDF
2) 爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
3) 高级爬虫,可以爬取大量异步渲染内容的网页
4) 模拟键盘输入、表单自动提交、登录网页等
5) 创建一个最新的自动化测试环境,实现 UI 自动化测试
6) 捕获站点的时间线,以便追踪网站、帮助分析网站性能问题
7) 用于测试 Chrome 扩展程序
运行环境
Nodejs 的版本不能低于 v7.6.0,因为需要支持 async, await.
需要最新的 chrome driver(安装 Puppeteer 时会自动下载)
Puppeteer 架构图
Puppeteer API 是分层的,并反映了浏览器的结构。
Puppeteer
使用 DevTools Protocol 与浏览器通信Browser
实例可以拥有多个浏览器上下文BrowserContext
实例定义了一个浏览会话,可以拥有多个页面Page
至少有一个 frame :main frame。可能还有其他由 iframe 创建的 frame 或标签Frame
至少有一个可执行上下文 - 默认执行上下文 - 在其中执行 frame 的 JavaScript 。一个 Frame 可能有与 extensions 有关联的其他执行上下文Worker
具有单个执行上下文,便于与 WebWorkers 交互
Puppeteer 初体验 —— 入门 Demo
官方入门 Demo 先感受一下基本用法:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch(); //启动一个无头浏览器
const page = await browser.newPage(); //打开一个标签页
await page.goto('https://example.com'); //跳转到指定的页面
await page.screenshot({path: 'example.png'}); // 对页面进行截图
await browser.close(); //关闭浏览器
})();
Puppeteer 模块
Puppeteer 模块提供了一种启动 Chromium 实例的方法。
示例
启动一个浏览器
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => {
const page = await browser.newPage();
await page.goto('https://www.google.com');
// 其他操作...
await browser.close();
});
puppeteer.launch([options])
可配置项(options)
属性 | 类型 | 说明 | 默认值 |
---|---|---|---|
ignoreHTTPSErrors | Boolean | 是否在导航期间忽略 HTTPS 错误 | false |
headless | Boolean | 是否以无头模式运行浏览器 | true(除非 devtools 选项是 true) |
devtools | Boolean | 是否为每个选项卡自动打开DevTools面板 | false |
timeout | Number | 等待浏览器实例启动的最长时间(以毫秒为单位),设置 0 禁用超时 | 30000(毫秒) |
slowMo | Number | 将 Puppeteer 操作减少指定的毫秒数(为了方便调试) | |
※ defaultViewport | Object | 为每个页面设置一个默认视口大小。如果为 null 的话就禁用视图口 | |
dumpio | Boolean | 是否将浏览器进程标准输出和标准错误输入到 process.stdout 和 process.stderr 中 | false |
查看更多:options 可配置项
※ defaultViewport 可选参数
属性 | 类型 | 说明 | 默认值 |
---|---|---|---|
width | Number | 页面宽度像素 | 800 |
height | Number | 页面高度像素 | 600 |
deviceScaleFactor | Number | 设置设备的缩放(可以认为是 dpr) | 1 |
isMobile | Boolean | 是否在页面中设置了 meta viewport 标签 | false |
hasTouch | Boolean | 指定viewport是否支持触摸事件 | false |
isLandscape | Boolean | 指定视口是否处于横向模式 | false |
puppeteer.connect(options)
这是将 Puppeteer 添加到已有的 Chromium 实例的方法。
可配置项(options)
属性 | 类型 | 说明 | 默认值 |
---|---|---|---|
browserWSEndpoint | String | 一个 浏览器 websocket 端点链接(必填) | |
ignoreHTTPSErrors | Boolean | 是否在导航期间忽略 HTTPS 错误 | false |
defaultViewport* | Object | 为每个页面设置一个默认视口大小。如果为 null 的话就禁用视图口 | |
slowMo | Number | 将 Puppeteer 操作减少指定的毫秒数(为了方便调试) |
Browser 对象
当 Puppeteer 连接到一个 Chromium 实例的时候会通过 puppeteer.launch 或 puppeteer.connect 创建一个 Browser 对象。
示例
示例1:使用 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();
});
示例2:断开连接和重连到 Browser
const puppeteer = require('puppeteer');
puppeteer.launch().then(async browser => {
// 存储节点以便能重新连接到 Chromium
const browserWSEndpoint = browser.wsEndpoint();
// 从 Chromium 断开和 puppeteer 的连接
browser.disconnect();
// 使用节点来重新建立连接
const browser2 = await puppeteer.connect({browserWSEndpoint});
// 关闭 Chromium
await browser2.close();
});
Browser Methods
browser.newPage()
:打开一个新的页面(创建一个新的 Page 对象)browser.disconnect()
:断开 Puppeteer 和浏览器的连接,但 Chromium 进程仍然在运行browser.close()
:关闭 Chromium 及其所有页面browser.wsEndpoint()
:返回浏览器 websocket 的地址
查看更多:Browser API
page 对象
Page 提供操作一个 tab 页或者 extension background page
(一个 chrome 拓展程序) 的方法。一个 Browser 实例可以有多个 Page 实例。
示例
示例1:创建一个 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();
});
示例2:用 on
或者 once
捕获 Page 事件,用 removeListener
移除事件监听
page.once('load', () => console.log('Page loaded!')); //捕获 page 实例的 load 事件
function logRequest(interceptedRequest) {
console.log('A request was made:', interceptedRequest.url());
}
page.on('request', logRequest); //监听 request 事件
// 一段时间后...
page.removeListener('request', logRequest); //移除request监听
Page Events
page.on('load')
:当页面的 load 事件被触发时触发page.on('close')
:当页面关闭时触发page.on('request')
:当页面发送一个请求时触发page.on('response')
:当页面的某个请求接收到对应的 response 时触发page.on('error')
:当页面崩溃时触发page.on('console')
:当页面js代码调用了 console 的某个方法时触发
Page Methods
基础类
page.goto(url[, options])
导航到指定地址page.close()
关闭页面page.setViewport(viewport)
设置页面视口page.evaluate(pageFunction[, ...args])
在页面实例上下文中执行方法page.setRequestInterception(value)
是否启用请求拦截器
cookie 类
page.cookies([...urls])
返回指定页面域名的 cookie(若未指定url,返回当前页面域名的 cookie)page.setCookie(...cookies)
设置 cookiepage.deleteCookie(...cookies)
删除指定 cookie
元素选择、操作类
page.$(selector)
document.querySelectorpage.$$(selector)
document.querySelectorAllpage.type(selector, text[, options])
模拟键盘输入内容page.click(selector[, options])
点击匹配元素page.tap(selector)
点击匹配元素(通过 page.touchscreen 点击)page.focus(selector)
使匹配元素获得焦点page.hover(selector)
使匹配元素获得hover状态page.select(selector, ...values)
选中匹配的选择器,触发change和input事件
waitFor 系列
page.waitForFunction(pageFunction[, options[, ...args]])
:等待函数执行完成page.waitForNavigation([options])
:等待页面跳转完成page.waitForRequest(urlOrPredicate[, options])
:等待匹配的请求page.waitForResponse(urlOrPredicate[, options])
:等待匹配的响应page.waitForSelector(selector[, options])
:等待指定的选择器匹配的元素出现在页面中page.waitForXPath(xpath[, options])
:等待指定的xpath匹配的元素出现在页面中page.waitForTimeout(milliseconds)
:等待的毫秒数 (v10.1.0 新增 )page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
:新版本中已废弃,使用waitForSelector
、waitForFunction
、waitForTimeout
代替
总之很实用类
page.pdf([options])
生成PDFpage.screenshot([options])
截图
查看更多:Page API
实战场景
篇幅太长,另开一篇嘿嘿:
Puppeteer 实战场景 —— 生成 PDF
参考链接
文档类
Puppeteer 官网:https://pptr.dev
Puppeteer 中文文档:https://learnku.com/docs/puppeteer/3.1.0
Puppeteer 中文文档(另一版):http://www.puppeteerjs.com/
经验帖
puppeteer (Nodejs版selenium )快速入门
puppetee 常用API
Puppeteer如何从多个HTMLS生成PDF
puppeteer 生成pdf,绝对解决你的需求