前言
在前端开发中,我们会有一些需要将当前页面转为图片或PDF的需求。通过调研发现目前Puppeteer这个库最符合诉求,Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协议控制 Chromium 或 Chrome。我们也可以理解为 通过 puppeteer 我们可以模拟我们日常对 chrome 浏览器的交互操作。总的来说有以下作用:
- 网络爬虫
- web 自动化测试
- 页面截图(PDF)
- 性能分析和测试
功能模块(具体功能)
puppeteer 主要分下以下几大功能点:
- 启动 chromium 监听浏览器对象 Browser 操作
- 通过浏览器对象 Browser 操作 page,Page 对象可以对页面元素内容的获取、插入、修改等操作
- 浏览器页面交互事件处理和监听如键盘、鼠标、touch 等
浏览器对象 Browser
- Puppeteer 入口模块提供了一种启动 Chromium 实例的方法。 下面就是使用 Puppeteer 进行自动化的一个典型示例:
ini
const puppeteer = require('puppeteer');
//先通过 puppeteer.launch() 创建一个浏览器实例 Browser 对象
const browser = await puppeteer.launch();
- browser 对象的操作监听
dart
//当 Puppeteer 从 Chromium 实例断开连接时被触发
browser.on('disconnected',()=>{
console.log('disconnected ------------');
})
//当目标的 url 改变时被触发
browser.on('targetchanged',()=>{})
页面对象 Page
- puppeteer 启动浏览器后会返回浏览器对象 browser 我们可以通过 browser 对象实现对浏览器状态的监听以及打开和关闭页面的操作
csharp
const page = await browser.newPage();
await page.goto('https://www.google.com');
// 其他操作...
await browser.close();
-
浏览器新建一个页面后会返回该页面的对象 page,通过该对象对页面元素内容的获取、插入、修改等操作,在自动化测试和网络爬虫我们会频繁的用到此对象,以下是常用的 API:
-
查询单个元素
javascript
//相当于js执行的document.querySelector方法,如果没有元素匹配则返回null
const bodyEle = await page.$("body")
- 查询所有符合条件的元素列表
scss
//相当于js执行的document.querySelectorAll方法,获取多个元素
page.$$(selector)
javascript
//此方法在页面内执行 Array.from(document.querySelectorAll(selector))然后把匹配到的元素数组作为第一个参数传给 pageFunction。
page.$$eval(selector, pageFunction[, ...args])
// 回调函数中的参数可以进行页面dom元素来操作
page.$$eval(selector, (ele)=>{
console.log(ele)
})
php
//此方法在页面内执行 Array.from(document.querySelector(selector))然后把匹配到的元作为第一个参数传给 pageFunction。
page.$eval(selector, pageFunction[, ...args])
浏览器常用操作
-
页面相关操作:
- page.goBack():导航到历史页面中的上一个页面
- page.goForward(): 导航到历史页面中的下一页
- page.close(): 关闭当期页面
- page.goto(url):跳转到对应的url
- page.reload(): 重新加载页面
-
键盘操作事件 Keyboard 对象:Keyboard 提供一个接口来管理虚拟键盘. 高级接口为 keyboard.type, 其接收原始字符, 然后在你的页面上生成对应的 keydown, keypress/input, 和 keyup 事件
- keyword.typ 输入到焦点元素中的文本,一般先要聚焦到需要输入文本的元素,然后进行输入
javascriptawait page.$("***"); //焦点元素输入文本 page.keyboard.type("******") //向元素ele中插入文本,page.type操作之前需要判断元素是否已经渲染成成功 await page.waitForSelector(selector, {visible: true, timeout: 1000 }); page.type(ele,text)
- 按下键盘(keydown)事件
- 松开键盘(keyup)事件
- 长按键盘(press)事件,一般组合事件中会用到
-
鼠标操作事件 mouse 对象: puppeteer 可以模拟用户鼠标移动,悬停、按下、松开的常规操作,具体使用方式如下
- 移动鼠标 move:移动鼠标到指定元素位置我们先要获取元素位置,获取元素位置的方法 boundingBox 具体用例如下
ini
const element = await page.$("#****");
//获取元素位置及宽高信息
let box = await element.boundingBox();
const x = box.x + box.width / 2;
const y = box.y + box.height / 2;
page.mouse.move(x, y);
-
鼠标按下、松开、点击,这些可以模拟真实的用户操作
-
mouse.move(x,y):鼠标移动到页面坐标为 x/y
-
mouse.down(): 操作按下鼠标左键
-
mouse.up(): 操作松开鼠标左键
-
mouse.click(x,y): 操作鼠标左键点击 x,y 位置
-
鼠标还有个特殊的操作 reset,可以通过 page.mouse.reset()重置鼠标的状态和位置。
-
鼠标操作中常会用到的一个 API,page.waitForTimeout(milliseconds),用来使脚本等待给定的毫秒数。
本文只是简单的介绍下puppeteer的使用,后续会通过实际应用来深入了解。