Puppeteer
先献上
地址:https://github.com/puppeteer/puppeteer
demo: https://try-puppeteer.appspot.com/
api: https://zhaoqize.github.io/puppeteer-api-zh_CN/
概述
通过 api 自动化控制 Chrome
如何使用
要求:node > v6.4.0 (如要使用 async / await,只有 Node v7.6.0 或更高版本才支持)
安装:yarn add puppeteer -S
能做什么
官方回答
- 生成页面 PDF。
- 抓取 SPA(单页应用)并生成预渲染内容(即“SSR”(服务器端渲染))。
- 自动提交表单,进行 UI 测试,键盘输入等。
- 创建一个时时更新的自动化测试环境。使用最新的 JavaScript 和浏览器功能直接在最新版本的 Chrome 中执行测试。
- 捕获网站的 timeline trace,用来帮助分析性能问题。
- 测试浏览器扩展。
总结
爬虫,抓取任意网站的页面数据
ui 流程自动化测试 按业务逻辑来编写测试案例,
性能分析 通过生成 json 文件,拖到开发者工具中 performace 中查看
可以监听网站发出的请求,可以拦截,抓取响应的数据
可以设置代理服务器来访问网站
可以设置不同终端设备模拟器,通过截图来查看最终页面呈现效果
可以设置 delay sleep 来模拟真人输入和操作
可以监听 console, 接口抛出的异常,设置 cookie,键盘输入,鼠标移动
基于我们的 egg.js 可以做定时任务,定时检测;实现一套前端页面监控,便于自测
X 像 12306 登陆页面验证码过于复杂的网站,抓取数据有点困难,需要根据不同网站,个个攻破
√ api 友好,官方维护
代码示例:
如何爬虫?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const puppeteer = require('puppeteer');
1. 准备工作 // window const browser = await puppeteer.launch({ headless: true, defaultViewport: { width: 1920, height: 1080, deviceScaleFactor: 1, }, }); // mac const browser = await puppeteer.launch({ headless: true, defaultViewport:null, executablePath: 'your chrome app path', // '/Applications/Google Chrome.app/' });
const page = await browser.newPage();
await browser.close();// 放在最后
// 准备工作结束
// 前往豆瓣网站,等待 dom 加载完成 await page.goto('https://movie.douban.com/', { waitUntil: 'networkidle0' }); await page.waitForSelector('.gaia-movie');
// 爬虫开始 const list = await page.evaluate(() => { const list = [...document.querySelectorAll(".list-wp .slide-page[data-index='0'] a")]; return list.map(el => { return { href: el.href.trim(), title: el.innerText.trim() }; }); });
consoele.log(list)
|
- ui流程: 模拟用户操作
1 2 3 4 5 6 7 8 9
| await page.goto('https://test-sat.meetsocial.cn/', { waitUntil: 'networkidle0' });// 前往某个网站 await page.focus('#loginName'); // 模拟聚焦用户名输入框 await page.type('#loginName', 'admin'); // 模拟用户名输入 await page.type('#password', '********'); // 模拟密码输入 await page.keyboard.press('Enter');// 模拟按键回车
const cardBtn = await page.$('.ant-card'); // 跳转新的页面 进入/channel await cardBtn.click(); // 点击事件 await page.waitForSelector('#facebook section');
|
- 使用trace性能分析(每个浏览器一次只能激活一个跟踪)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| await page.tracing.start({ path: './file/' + moment().format('YYYY-MM-DD-HH-mm-ssss') + '-trace.json', }); await page.goto('https://test-sat.meetsocial.cn/', { waitUntil: 'networkidle0' }); await page.tracing.stop(); 4. 拦截请求
await page.setRequestInterception(true); page.on('request', interceptedRequest => { // console.log('interceptedRequest: ', interceptedRequest); // if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg')) // interceptedRequest.abort(); // else interceptedRequest.continue(); }); page.on('response', response => { console.log(response.url()); });
|
- 截图输出
1
| await page.screenshot({ path: './file/' + createTime + '.png', fullPage: true });
|
- 模拟器 (手机 pad)
1
| await page.emulate(iPhone);
|