关注公众号“执鸢者”,回复“材料”获取500G材料(各“兵种”均有),还有业余交换群等你一起来洒脱。(哈哈)

本文次要讲述一下Google出版并始终在一直保护的神器puppeteer,通过学习本文你将理解其根本应用和罕用性能。

一、Puppeteer简介

Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协定管制 Chromium 或 Chrome,利用Puppeteer能够获取页面DOM节点、网络申请和响应、程序化操作页面行为、进行页面的性能监控和优化、获取页面截图和PDF等,利用该神器就能够操作Chrome浏览器玩出各种花色。

二、Puppeteer外围组成构造

Puppeteer的构造也反映了浏览器的构造,其外围构造如下所示:
  1. Browser:这是一个浏览器实例,能够领有浏览器上下文,可通过 puppeteer.launch 或 puppeteer.connect 创立一个 Browser 对象。
  2. BrowserContext:该实例定义了一个浏览器上下文,可领有多个页面,创立浏览器实例时默认会创立一个浏览器上下文(不能敞开),此外能够利用 browser.createIncognitoBrowserContext()创立一个匿名的浏览器上下文(不会与其它浏览器上下文共享cookie/cache).
  3. Page:至多蕴含一个主框架,除了主框架外还有可能存在其它框架,例如iframe。
  4. Frame:页面中的框架,在每个工夫点,页面通过page.mainFrame()和frame.childFrames()办法裸露以后框架的细节。对于该框架中至多有一个执行上下文
  5. ExecutionCOntext:示意一个JavaScript的执行上下文。
  6. Worker:具备单个执行上下文,便于与 WebWorkers 交互。

三、根本应用和罕用性能

该神器整体应用起来比较简单,上面就开始咱们的应用之路。

3.1 启动Browser

外围函数就是异步调用puppeteer.launch()函数,依据相应的配置参数创立一个Browser实例。
const path = require('path');const puppeteer = require('puppeteer');const chromiumPath = path.join(__dirname, '../', 'chromium/chromium/chrome.exe');async function main() {    // 启动chrome浏览器    const browser = await puppeteer.launch({        // 指定该浏览器的门路        executablePath: chromiumPath,        // 是否为无头浏览器模式,默认为无头浏览器模式        headless: false    });}main();

3.2 拜访页面

拜访页面首先须要创立一个浏览器上下文,而后基于该上下文创立一个新的page,最初指定要拜访的网址。
async function main() {    // 启动chrome浏览器    // ……    // 在一个默认的浏览器上下文中被创立一个新页面    const page1 = await browser.newPage();    // 空白页刚问该指定网址    await page1.goto('https://51yangsheng.com');    // 创立一个匿名的浏览器上下文    const browserContext = await browser.createIncognitoBrowserContext();    // 在该上下文中创立一个新页面    const page2 = await browserContext.newPage();    page2.goto('https://www.baidu.com');}main();

3.3 设施模仿

常常须要不同类型的机型的浏览后果,此时就能够采纳设施模仿实现,上面模仿一个iPhone X的设施的浏览器后果
async function main() {    // 启动浏览器    // 设施模仿:模仿一个iPhone X    // user agent    await page1.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1')    // 视口(viewport)模仿    await page1.setViewport({        width: 375,        height: 812    });        // 拜访某页面}main();

3.4 获取DOM节点

获取DOM节点有两种形式,一种形式是间接调用page所带的原生函数,另一种是通过执行js代码获取。
async function main() {    // 启动chrome浏览器    const browser = await puppeteer.launch({        // 指定该浏览器的门路        executablePath: chromiumPath,        // 是否为无头浏览器模式,默认为无头浏览器模式        headless: false    });    // 在一个默认的浏览器上下文中被创立一个新页面    const page1 = await browser.newPage();    // 空白页刚问该指定网址    await page1.goto('https://www.baidu.com');    // 期待title节点呈现    await page1.waitForSelector('title');    // 用page自带的办法获取节点    const titleDomText1 = await page1.$eval('title', el => el.innerText);    console.log(titleDomText1);// 百度一下    // 用js获取节点    const titleDomText2 = await page1.evaluate(() => {        const titleDom = document.querySelector('title');        return titleDom.innerText;    });    console.log(titleDomText2);}main();

3.5 监听申请和响应

上面就来监听一下百度中某一js脚本的申请和响应,request事件是监听申请,response事件是监听响应。
async function main() {    // 启动chrome浏览器    const browser = await puppeteer.launch({        // 指定该浏览器的门路        executablePath: chromiumPath,        // 是否为无头浏览器模式,默认为无头浏览器模式        headless: false    });    // 在一个默认的浏览器上下文中被创立一个新页面    const page1 = await browser.newPage();    page1.on('request', request => {        if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {            console.log(request.resourceType());            console.log(request.method());            console.log(request.headers());        }    });    page1.on('response', response => {        if (response.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {            console.log(response.status());            console.log(response.headers());        }    })    // 空白页刚问该指定网址    await page1.goto('https://www.baidu.com');}main();

3.6 拦挡某一申请

默认状况下request事件只有只读属性,不可能拦挡申请,若想拦挡该申请则须要通过page.setRequestInterception(value)启动申请拦截器,而后利用request.abort, request.continue 和 request.respond 办法决定该申请的下一步操作。
async function main() {    // 启动chrome浏览器    const browser = await puppeteer.launch({        // 指定该浏览器的门路        executablePath: chromiumPath,        // 是否为无头浏览器模式,默认为无头浏览器模式        headless: false    });    // 在一个默认的浏览器上下文中被创立一个新页面    const page1 = await browser.newPage();    // 拦挡申请开启    await page1.setRequestInterception(true);// true开启,false敞开    page1.on('request', request => {        if (request.url() === 'https://s.bdstatic.com/common/openjs/amd/eslx.js') {            // 终止该申请            request.abort();            console.log('该申请被终止!!!');        }        else {            // 持续该申请            request.continue();        }    });    // 空白页刚问该指定网址    await page1.goto('https://www.baidu.com');}main();

3.7 截图

截图是一个很有用的性能,通过截取就能够保留一份快照,不便前期问题的排查。(注:在无头模式下进行截图,否则截的图可能有问题)
async function main() {    // 启动浏览器,拜访页面的操作        // 截屏操作,应用Page.screenshot函数    // 截取整个页面:Page.screenshot函数默认截取整个页面,加上fullPage参数就是全屏截取    await page1.screenshot({        path: '../imgs/fullScreen.png',        fullPage: true    });    // 截取屏幕中一个区域的内容    await page1.screenshot({        path: '../imgs/partScreen.jpg',        type: 'jpeg',        quality: 80,        clip: {            x: 0,            y: 0,            width: 375,            height: 300        }    });    browser.close();}main();

3.8 生成pdf

除了利用截图保留快照外,还能够应用pdf保留快照。
async function main() {    // 启动浏览器,拜访页面的操作        // 依据网页内容生成pdf文件,应用Page.pdf——留神:必须在无头模式下才能够调用    await page1.pdf({        path: '../pdf/baidu.pdf'    });    browser.close();}main();

1.如果感觉这篇文章还不错,来个分享、点赞吧,让更多的人也看到

2.关注公众号执鸢者,支付学习材料(前端“多兵种”材料),定期为你推送原创深度好文