Puppeteer 是 Google Chrome 团队官方出的一个 node 库,它提供了一个 API 来控制 DevTools 协议上的 Chrome 或 Chromium。Puppeteer默认是无头(Headless)运行,可以在无 UI 的情况下调用 Chrome、Chromium 的功能,适用于页面截图、页面PDF、爬虫、自动化处理等各种场景。
认识 Headless Chrome?
- Chrome 在无界面的环境。
- 可以通过命令行或者程序语言操作 Chrome。
- 在启动 Chrome 时添加参数 --headless,便可以 headless 模式启动 Chrome。
Puppeteer 能做什么?
“Most things that you can do manually in the browser can be done using Puppeteer” 这是官方给 Puuetter 的介绍,可以在浏览器中手动完成的大部分事情都可以使用 Puppeteer 完成,如下:
- 生成页面的屏幕截图和pdf文件。
- 抓取一个 SPA 单页并生成预渲染的内容,即 SSR(服务器端渲染)。
- 自动化表单提交、UI测试、键盘输入等。
- 创建一个最新的、自动化的测试环境。使用最新的 JavaScript 和浏览器特性,在最新版本的 Chrome 中直接运行测试。
- 捕获页面的时间线跟踪,以帮助诊断性能问题。
- 测试 Chrome 扩展。
Puppeteer 结构
- Puppeteer 通过 DevTools 协议控制 Chrome、Chromium 浏览器。
- 一个 Browser 实例可以包含多个BrowserContexts(浏览器上下文),就像我们打开一个普通的 Chrome 之后又打开一个隐身模式的 Chrome。
- 一个BrowserContext可以包含多个Page。
- 一个 Page 包含至少一个主 Frame,也可以包含其他 Frame,在主 Frame 中通过 iframe 标签创建。
- 一个 Frame 包含至少一个ExecutionContext(执行上下文),也可以包含其他由 Chrome 插件创建的执行上下文。
- 一个 Workder 包含一个执行上下文,由 webWorker 创建。
Puppeteer API
Puppeteer 的大部分 API 的返回值都是 Promise,故经常使用 async await 来处理异步操作。Puppeteer 常用的 API 如下:
类名 | 描述 |
---|---|
Puppeteer | 主要用于创建一个浏览器实例,也可以用来下载新的 Chromium,或者设置浏览器的默认参数 |
BrowserFetcher | 用于下载和管理 Chromium |
Browser | 可以创建一个或多个 Page |
BrowserContext | 创建一个隐身模式的浏览器时需要用到 |
Page | 主要 API,用于操作一个页面,下面会进一步介绍 |
Worker | 用于处理 WebWorker |
Keyboard | 可以触发键盘按键 |
Mouse | 可以触发鼠标动作 |
TouchScreen | 可以触发触摸屏的动作 |
Frame | 常用于处理包含多个 frame 的页面。page 中的很多方法就是直接调用的主 frame 的方法 |
ExecutionContext | 执行上下文存在于 frame、浏览器插件、worker 中。可在这里执行js代码 |
JSHandle | 通过 page.evaluateHandle 生成,用于将页面中的 handler 挑出来传递使用 |
ElementHandle | 通过 page.$ 生成,用于将页面中某个元素的 handler 挑出来传递使用 |
Request | 在 page.setRequestInterception 方法中使用,可以处理页面的请求 |
Response | 表示页面接收到的响应 |
Page
Page 是 Puppeteer 中最重要的一个 API,核心所在,常用的 Page API 如下:
设置页面环境
方法名 | 描述 |
---|---|
page.emulate | 设置 viewport 和 ua |
page.setViewport | 设置 viewport |
page.setUserAgent | 设置 ua |
page.setRequestInterception | 中断所有请求,并可以修改请求的返回值 |
page.setCacheEnabled | 设置缓存是否开启 |
page.setGeolocation | 设置地理位置 |
page.deleteCookie | 删除 cookies |
page.setCookie | 设置 cookies |
模拟动作
模仿用户在浏览器实际的操作
方法名 | 描述 |
---|---|
page.tap | 点击 |
page.focus | input等元素获得焦点 |
page.hover | 鼠标 |
page.type | 在指定元素中输入内容 |
page.select | 选中选择标签的某个选项 |
等待
如在爬虫过程中,需要等待某个操作执行完才能进入下一步时
方法名 | 描述 |
---|---|
page.waitFor | 等待某个元素渲染出来,或者某个函数执行之后返回 true,或者直接等待指定的时间 |
page.waitForSelector | 等待某个元素被渲染 |
page.waitForFunction | 等待某个函数执行之后返回 true |
page.waitForNavigation | 等待页面跳转 |
page.waitForRequest | 等待某个特定的请求被发出 |
page.waitForResponse | 等待某个特定的请求收到了回应 |
获取元素,自定义方法
方法名 | 描述 |
---|---|
page.$ | 等于 document.querySelector,返回 ElementHandle, |
page.? | 等于 document.querySelectorAll |
page.$eval | 将 document.querySelector 获取的结果传递给 pageFunction |
page.?eval | 同上,使用的是 document.querySelectorAll |
page.evaluate | 可执行自定义JS |
页面跳转
方法名 | 描述 |
---|---|
page.goto | 跳转页面 |
page.close | 关闭 |
page.goBack | 后退 |
page.goForward | 前进 |
page.reload | 刷新 |
获取内容
方法名 | 描述 |
---|---|
page.screensho | 截屏 |
page.pdf | 生成 pdf |
page.content | 获取整个页面内容 |
page.title | 获取页面 title |
page.url | 获取页面 url |
page.cookies | 获取 cookies |
以上主要是整理了一些知识点,后面会写一篇实践篇。