puppeteer是一种谷歌开发的Headless Chrome,由于puppeteer的出现,业内许多自动化测试库中止维护,好比PhantomJS,Selenium IDE for Firefox 。javascript
官方给了一些功能:前端
其实对于这么一个浏览器,咱们能作的还有不少,好比前端监控,按期查询页面异常。这种思想产生的page-monitor。主要的功能其实就是基于它是一个浏览器,它能够模拟用户输入。能作什么依赖你的想象。java
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('http://open.toutiao.com', {waitUntil: 'networkidle2'}); await page.pdf({path: 'hn.pdf', format: 'A4'}); await browser.close(); })();
puppeteer是基于node v6.4.0,可是await/async的语法须要node v7.6.0以上才支持。node
能够npm i puppeteer
而后在命令行看一下效果。
代码都是api没有什么能够讲的。须要说的一点就是open.toutiao.com下面的文章内容都是异步接口请求,puppeteer是怎么获取内容的?git
page.goto的配置项waitUntil:networkidle2, 等待一直到500ms内的请求数不超过2个。其实不保证准确得到内容,那把等待时间写长一点就能够了。
await page.waitFor(2000);
github
puppeteer.launch({headless: false)
,再放慢puppeteer执行的动做puppeteer.launch({headless: false, slowMo: 250})
,就能够轻松调试。page.on('console', msg => console.log('PAGE LOG:', msg.text()));
事件监听轻松打出页面的log。这里爬一下头条的新闻标题:chrome
(async () => { const browser = await puppeteer.launch({headless: false, slowMo: 250}); const page = (await browser.pages())[0]; page.on('console', msg => console.log('PAGE LOG:', msg.text())); await page.goto('https://open.toutiao.com'); await page.evaluate(() => console.log(`url is ${location.href}`)); const newsTitle = await page.evaluate((sel) => { const $els = document.querySelectorAll(sel); return Array.from($els).map((v) => { console.log(v.innerText); // 会被page.on 'console' 监听到 return v.innerText }) }, 'section h3'); console.log(newsTitle) // 能够处理新闻标题。 await page.screenshot({path: 'toutiao.png'}); // 屏幕快照 await browser.close(); })();
这个功能用途挺多的,好比自动登录,e2e测试,刷赞,抢票什么的,固然若是能跳过验证码的话。npm
模拟输入用户名和密码。json
await page.goto('https://github.com/login'); await page.click('#login_field'); await page.type('username'); await page.click('#password'); await page.type('password'); await page.click('#login > form > div.auth-form-body.mt-3 > input.btn.btn-primary.btn-block'); await page.waitForNavigation();
puppetter提供了page.focus,page.click,page.type,page.$eval(获取dom属性)等等api,鼠标位置,按键按下,tap,页面跳转众多用户可操做的api,均可以经过程序来模拟。api
对这种模拟登录,puppeteer还贴心的提供了这种api - -!
page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
以前分享过的testcafe,跟puppeteer的api很是像,testcafe是一个自动化测试框架,他与puppeteer不一样的一点就是他集成了mocha断言库。
puppeteer和testcafe都提供了一套自动化测试的环境。puppeteer作e2e的测试须要本身选一个断言库,不过无伤大雅。
puppeteer比testcafe好的一点就是支持请求拦截,记得当初用testcafe测试请求是否被发出用了不少黑科技,提过issue。。
const puppeteer = require('puppeteer'); puppeteer.launch({headless: false, slowMo: 250}).then(async browser => { const page = await browser.newPage(); await page.setRequestInterception(true); page.on('console', msg => console.log('PAGE LOG:', msg.text())); page.on('request', interceptedRequest => { if (interceptedRequest.url().endsWith('.png') || interceptedRequest.url().endsWith('.jpg')) interceptedRequest.abort(); else interceptedRequest.continue(); }); await page.goto('https://open.toutiao.com'); // await browser.close(); });
提供了request,response事件,能够拦截请求,首先须要打开这个开关await page.setRequestInterception(true);
。
这里的例子就是停掉全部的png和jpg请求。
拦截能作的东西有不少,好比一些爬虫能够经过拦截请求捕获一些数据,来处理一些东西。
puppeteer能够经过page.setViewport,page.setUserAgent来修改访问的环境。
await page.setViewport({ width: 1920, height: 1080 }); await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36');
puppeteer/DeviceDescriptors
还给咱们封装好了一些环境,好比:
const puppeteer = require('puppeteer'); const devices = require('puppeteer/DeviceDescriptors'); const iPhone = devices['iPhone 6']; puppeteer.launch().then(async browser => { const page = await browser.newPage(); await page.emulate(iPhone); // emulate的配置有Viewport,UserAgent等等。以前的setUserAgent等方法是它的语法糖。 await page.goto('https://www.google.com'); // other actions... await browser.close(); });
能够生成一个trace.json的文件,供chrome控制台解析,await page.metrics()
还能够给出一些性能测试的数据。
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.tracing.start({path: 'trace.json'}) await page.goto('https://open.toutiao.com') await page.tracing.stop() const metrics = await page.metrics() console.log(metrics) await browser.close(); })(); // output { Timestamp: 27888.820538, Documents: 2, Frames: 1, JSEventListeners: 58, Nodes: 171, LayoutCount: 20, RecalcStyleCount: 26, LayoutDuration: 0.042335, RecalcStyleDuration: 0.010091, ScriptDuration: 0.124838, TaskDuration: 0.000039, JSHeapUsedSize: 6388448, JSHeapTotalSize: 10334208 }