Puppeteer的入门与实践
1.背景
在web端自动化测试中目前使用较多的是selenium、webdriver等的解决方案,这些的依赖较多。puppeteer是一款基于chrome的自动化测试以及爬虫工具。
2.了解puppeteer
imagePuppeteer是谷歌官方出品的一个通过DevTools协议控制headless Chrome的Node库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。
Puppeteer 核心功能
-
利用网页生成PDF、图片
-
爬取SPA应用,并生成预渲染内容(即“SSR” 服务端渲染)
-
可以从网站抓取内容
-
自动化表单提交、UI测试、键盘输入等
-
帮你创建一个最新的自动化测试环境(chrome),可以直接在此运行测试用例
-
捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题
3 环境和安装
Puppeteer因为是一个npm的包,所以安装很简单:(在此之前需要安装node)
npm i puppeteer
或者
yarn add puppeteer
Puppeteer安装时自带一个最新版本的Chromium,可以通过设置环境变量或者npm config中的PUPPETEER_SKIP_CHROMIUM_DOWNLOAD跳过下载。如果不下载的话,启动时可以通过puppeteer.launch([options])配置项中的executablePath指定Chromium的位置。
4 使用和例子
Puppeteer类似其他框架,通过操作Browser实例来操作浏览器作出相应的反应。
const puppeteer = require('puppeteer');(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('http://google.com'); await page.screenshot({path: 'example.png'}); await page.pdf({path: 'example.pdf', format: 'A4'}); await browser.close();
})();
上述代码通过puppeteer.launch方法生成了一个browser的实例,对应于浏览器,launch方法可以传入配置项,比较有用的是在本地调试时传入{headless:false}可以关闭headless模式。
const browser = await puppeteer.launch({headless:false})
browser.newPage方法可以打开一个新tab并且返回这个tab的事例page,通过page的各种方法可以对页面进行常用操作,如元素查找、点击、输入等的操作。上述代码中page.screenshot是截屏,page.pdf是打印pdf。
puppeteer提供了一个强大的方法page.evaluate,来看下这个函数
page.evaluate(pageFunction, …args)
-
pageFunction
<[function]|[string]> 要在页面实例上下文中执行的方法 -
...args
<…[Serializable]|[JSHandle]> 要传给pageFunction
的参数 -
返回: <[Promise]<[Serializable]>>
pageFunction
执行的结果
如果pageFunction返回的是[Promise],page.evaluate
将等待promise完成,并返回其返回值。
如果pageFunction返回的是不能序列化的值,将返回undefined
来看下事例:
给pageFunction
传参数示例:
-
const result = await page.evaluate(x => {
-
return Promise.resolve(8 * x);
-
}, 7); // 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"
</pre>
可以通过该函数向页面注入我们的函数,这样就有了无限可能
4 调试技巧
先来了解launch方法:
puppeteer.launch([options])
-
options
<[Object]> 在浏览器上设置的一组可配置选项。 有以下字段: -
ignoreHTTPSErrors
<[boolean]> 是否在导航期间忽略 HTTPS 错误. 默认是false
。 -
headless
<[boolean]> 是否以 无头模式 运行浏览器。默认是true
,除非devtools
选项是true
。 -
executablePath
<[string]> 可运行 Chromium 或 Chrome 可执行文件的路径,而不是绑定的的 Chromium。如果executablePath
是一个相对路径,那么他相对于 当前工作路径 解析。 -
slowMo
<[number]> 将 Puppeteer 操作减少指定的毫秒数。这样你就可以看清发生了什么,这很有用。 -
args
<[Array]<[string]>> 传递给浏览器实例的其他参数。 这些参数可以参考 这里。 -
ignoreDefaultArgs
<[boolean]> 不要使用puppeteer.defaultArgs()
。危险的选项; 谨慎使用。默认是false
。 -
handleSIGINT
<[boolean]> Ctrl-C 关闭浏览器进程。默认是true
。 -
handleSIGTERM
<[boolean]> 关闭 SIGTERM 上的浏览器进程。默认是true
。 -
handleSIGHUP
<[boolean]> 关闭 SIGHUP 上的浏览器进程。默认是true
. -
timeout
<[number]> 等待浏览器实例启动的最长时间(以毫秒为单位)。默认是30000
(30 秒). 通过0
来禁用超时。 -
dumpio
<[boolean]> 是否将浏览器进程标准输出和标准错误输入到process.stdout
和process.stderr
中。默认是false
。 -
userDataDir
<[string]> 用户数据目录 路径。 -
env
<[Object]> 指定浏览器可见的环境变量。默认是process.env
。 -
devtools
<[boolean]> 是否为每个选项卡自动打开DevTools面板。如果这个选项是true
,headless
选项将会设置成false
。 -
pipe
<[boolean]> 通过管道而不是WebSocket连接到浏览器。默认是false
。 -
returns: <[Promise]<[Browser]>> 浏览器实例支持 Promise。
该方法启动具有给定参数的浏览器实例。当父节点 node.js 进程关闭时,浏览器将被关闭。
- chrome提供了headless模式,在puppeteer中可以在launch中配置headless为false关掉无界面模式,查看浏览器显示的内容。使用以下命令可以启动完整版浏览器:
const browser = await puppeteer.launch({headless: false})
- 减慢速度,slowMo选项以指定的毫秒减慢Puppeteer的操作。这是另一个看到发生了什么的方法:
const browser = await puppeteer.launch({ headless:false, slowMo:250});
下篇文章将会介绍page相关的操作。
本文首发于 https://mp.weixin.qq.com/s/smK6xGWyzEc25-e7rNcXJw