开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情
前言
最近因为总是在测试方面花太多的时间,挤掉了很多摸鱼的时间,这是得不偿失,于是自己想做一个自动化测试工具,可以改变屏幕大小,可以截图,于是首选pupeteer
, 那么要使用它,得先把他常用的api
研究一下, 今天这节课就是pupeteer
的启蒙课程
pupeteer
puppeteer
是Chrome
团队开发的一个node
库- 可以通过
api
来控制浏览器的行为,比如点击,跳转,刷新,在控制台执行js
脚本等等 - 通过这个工具可以用来写爬虫,自动签到,网页截图,生成pdf,自动化测试等
安装pupeteer
npm i puppeteer -D
玩转puppeteer
常用浏览器设置
const browser = await puppeteer.launch({
headless: false, // true不会打开浏览器. 默认为true
timeout: 15000, //设置超时时间,
}); //打开浏览器
打开一个新的标签页
const page = await browser.newPage(); //打开一个空白页
页面跳转
// 建议使用这种方式,可以防止浏览器超时
await page.goto("https://www.baidu.com", { timeout: 3000 }).then(() => {
console.log('跳转百度页面成功');
}, () => {
console.log('跳转成功,加载超时');
}); //在地址栏输入网址并等待加载
设置页面大小,方便多屏幕测试
await page.setViewport({
width: 400,
height: 300,
isMobile: true // 要不要包含`meta viewport` 标签. 默认 `false`。
});
截图功能
await page.screenshot({
path: "baidu.png", // 图片保存路径
fullpage: true // 是否截取全屏幕
}); //截个图
在输入框输入内容,并点击按钮
await page.type('#index-kw', 'puppeteer')
await page.click('#index-bn')
(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();//关掉浏览器
})();
const puppeteer=require('puppeteer');
const fs=require('fs');
(async function () {
const browser=await puppeteer.launch({headless:false});
const page=await browser.newPage();
await page.goto('https://juejin.im/tag/%E5%89%8D%E7%AB%AF', { waitUntil: 'networkidle2' });
await page.waitFor(500);
let comments = await page.$$eval('a.title', els => { return els.map(item => item.innerText); }); fs.writeFileSync('comments.txt',comments.join('\r\n'),'utf8');
await browser.close();
})();
等待导航成功
await page.waitForNavigation({
waitUntil: 'domcontentloaded',
timeout: 600000
});
我再使用这个waitForNavigation
一直发生超时的问题
Error: Navigation Timeout Exceeded: 30000ms exceeded
解决方案以及原因可以参考这篇文章
waitForNavigation doesn't work after clicking a link #1412
waitUntil
waitUntil
代表什么时候才认为导航加载成功。
load
: window.onload事件被触发时候完成导航,某些情况下它根本不会发生。domcontentloaded
: Domcontentloaded事件触发时候认为导航成功networkidle0
: 在 500ms 内没有网络连接时就算成功(全部的request结束),才认为导航结束networkidle2
: 500ms 内有不超过 2 个网络连接时就算成功(还有两个以下的request),就认为导航完成。
我们对比了下加载时长 networkidle0> networkidle2>load>domcontentloaded
使用networkidle0
的时候,随时可能网络加载时间在2s以上。我们希望500ms的时长是可配置的,因为500ms太长了。
完整代码
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
headless: false, // true不会打开浏览器. 默认为true
timeout: 15000, //设置超时时间,
}); //打开浏览器
const page = await browser.newPage(); //打开一个空白页
await page.setViewport({
width: 400,
height: 300,
isMobile: true
});
// 建议使用这种方式,可以防止浏览器超时
await page.goto("https://www.baidu.com", { timeout: 60000 }).then(() => {
console.log('跳转百度页面成功');
}, () => {
console.log('跳转成功,加载超时');
}); //在地址栏输入网址并等待加载
await page.type('#kw', '你好');
page.click('#su');
await page.waitForNavigation({
waitUntil: 'domcontentloaded',
timeout: 60000
});
await page.screenshot({
path: "baidu.png", // 图片保存路径
fullpage: true // 是否截取全屏幕
}); //截个图
await browser.close(); //关掉浏览器
})();