引言
Puppeteer是谷歌官方出品的一个通过DevTools协议控制headless Chrome的Node库。可以通过Puppeteer的提供的api直接控制Chrome模拟大部分用户操作来进行UI Test或者作为爬虫访问页面来收集数据。
很多同学会有疑问这和Selenium有什么不同。Selenium能做的事Puppeteer基本都能做,并且还可以做一些Selenium不能做的事。不过最吸引我的是它可以以headless模式运行,意思就是它执行时不用打开浏览器界面。有的同学说了以前Selenium也有提供过类似的Driver,但是比较鸡肋。
更多信息可以查看:https://github.com/puppeteer/puppeteer
前提条件
在学习此教程之前要有对Javascript, ES6+和Node.js有一定了解。
并安装最新版本的Node.js和NPM工具
安装
新建文件夹puppeteer-demo
cd puppeteer-demo
npm init -y --初始化项目
npm i puppeteer
使用
Puppeteer要求最低的Node版本是v6.4.0,但是我们将要用到async/await,这个特性是v7.6.0才支持的,所以要确保升级Node到最新版本。接下来我们会演示一些例子。
1.用Puppeteer生成百度首页的截图
首先我们在我们项目的根目录创建一个文件screenshot.js,然后把以下代码片断贴进去
const puppeteer = require('puppeteer')
const main = async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://www.baidu.com')
await page.screenshot({ path: 'baidu.png' })
await browser.close()
}
main()
首先,我们引用了puppeteer的包,然后我们调用了launch方法初始化了实例,这个方法是一个异步方法,它会返回一个Promise。所以我使用await得一个browser实例。然后我们调用newPage创建一个page,然后打开百度,然后截图。
现在我们在终端执行一下以上脚本看一下效果。
node screenshot
等5、6秒,我们可以在项目看根目录看到一个截图baidu.png。
默认的可视区域大小是800X600,我可以用Page.setViewport()改变,我们改成1920px x 1080px。在goto之前插入以下代码:
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
})
然后把把保存的图片名称改baidu2.png
await page.screenshot({ path: 'baidu2.png' })
最终代码如下:
const puppeteer = require('puppeteer')
const main = async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
})
await page.goto('https://www.baidu.com')
await page.screenshot({ path: 'baidu2.png' })
await browser.close()
}
main()
再执行一次。
2.用Puppeteer保存PDF
再创建一个文件pdf.js, 粘贴如下代码:
const puppeteer = require('puppeteer')
const main = async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto('https://www.baidu.com', { waitUntil: 'networkidle2' })
await page.pdf({ path: 'hn.pdf', format: 'A4' })
await browser.close()
}
main()
我们在原来screenshot基础上只改了两行代码。
await page.goto('https://www.baidu.com', { waitUntil: 'networkidle2' })
await page.pdf({ path: 'hn.pdf', format: 'A4' })
networkidle2 对于进行长时间轮询或附加其他活动的页面非常有用,在500毫秒内不超过两个网络连接时,才认为导航已完成。
执行如下命令,看一下结果。会在根目录一下生成一个叫hn.pdf.
node pdf
3.搜索
再新建一个search.js, 粘贴如下代码:
const puppeteer = require('puppeteer');
const main = async () => {
const browser = await puppeteer.launch({headless: false})
const page = await browser.newPage()
await page.emulate(puppeteer.devices['iPhone X']);
await page.goto('https://www.baidu.com')
await page.type('#kw', 'puppeteer', {delay: 100});
page.click('#su')
await page.waitFor(1000);
await browser.close()
}
main()
headless: false 表示以Chrome UI的形式运行,方便看到效果。
await page.emulate(puppeteer.devices['iPhone X']); 这里是模拟一个手机屏幕。
page.click('#su') 元素定位是基于Css Selector。
结语
本文只是从UI自动化的角度做了简单介绍,其他特性待大家自己去探索。当然你也可以引入Jest单元测试框架,打造成自己的自动化测试框架。
本文暂时没有评论,来添加一个吧(●'◡'●)