Puppeteer实践-节省时间的利器

前言

看网上大多提到Puppeteer都是用它来做自动化测试,爬虫等等,而我在看到这个工具的第一想法是,它能否帮我提高开发过程中使用工具的效率。

在我的工作环境中,线上服务查慢接口,看日志等等需要首先登录jumpserver,再一步步寻址找到我需要的工具,点开它,选择自己需要的服务查看日志,查看耗时等等,这个过程鼠标点击好多次,重复工作很多,我就想能否节省前面这些步骤的时间。

直接给出效果吧

以上效果除了登录时候需要输入下验证码,之后没有移动鼠标,都有代码自行完成,包括自动打开树状结构菜单,自动选择skywalking,自动在打开的界面点击确认,自动选择最近7天,自动选择我要选择的项目,自动切换模式。

当你平时工作中看个东西有一堆固定的前置操作的时候,就可以想到,是否可以用它节省你的时间

执行代码

json 复制代码
import puppeteer from 'puppeteer';

(async () => {
    // Launch the browser and open a new blank page
    const browser = await puppeteer.launch({
        headless: false,
        defaultViewport: null,
        args: ['--start-maximized']
    });
    const context = browser.defaultBrowserContext();

    // 要查看哪个项目的skywalking
    let project = 'project-center';

    // 设置默认权限
    context.overridePermissions('https://jumpserver.xxx.com.cn/luna/', ['clipboard-read']);
    
    const page = await browser.newPage();

    await page.goto('https://jumpserver.xxx.com.cn/core/auth/login/?next=/luna/');
   
    // await page.mouse.click(1389,383);

    await page.waitForSelector('#id_username')
    
    // 替换为用户名和密码输入框的选择器
    await page.type('#id_username', '真实用户名');
    await page.type('#password', '真实密码');

    const captchaClassExists = await page.$('.captcha')
    if(captchaClassExists){
        await page.waitForSelector('#AssetTree_3_a');
    }else{
        await page.click('#login-form > div:nth-child(6) > button')
    }

    await new Promise(r => setTimeout(r, 1000));
    const [elementHandle] = await page.$x('//*[@id="AssetTree_3"]');
    if (elementHandle) {
        await elementHandle.click();
    }

    await new Promise(r => setTimeout(r, 500));
    await page.waitForSelector('#AssetTree_5')
    await page.click('#AssetTree_5')

    await new Promise(r => setTimeout(r, 500));
    await page.waitForSelector('#AssetTree_7')
    await page.click('#AssetTree_7')

    await new Promise(r => setTimeout(r, 500));
    await page.waitForSelector('#AssetTree_12')
    await page.click('#AssetTree_12')

    await page.waitForSelector('#mat-dialog-0 > elements-asset-tree-dialog > div > div.dialog-body.mat-dialog-content > mat-dialog-actions > button')
    await page.click('#mat-dialog-0 > elements-asset-tree-dialog > div > div.dialog-body.mat-dialog-content > mat-dialog-actions > button')
    
    await new Promise(r => setTimeout(r, 10000));

    // 确认60分钟警告
    await placeMarker(page, 1148, 450);
    await page.mouse.click(1148, 450);

    // 选择最近7天
    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 1244, 102);
    await page.mouse.click(1244, 102);

    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 913, 288);
    await page.mouse.click(913, 288);

    // 选择trace
    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 795, 226);
    await page.mouse.click(795, 226);
    // 选择输入框
    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 639, 280);
    await page.mouse.click(639, 280);

    // 输入具体的项目名
    await new Promise(r => setTimeout(r, 100));
    await page.keyboard.type(project)

    // 选择具体的项目
    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 639, 332);
    await page.mouse.click(639, 332);

    // 选择Duration
    await new Promise(r => setTimeout(r, 1000));
    await placeMarker(page, 816, 381);
    await page.mouse.click(816, 381);

    await new Promise(r => setTimeout(r, 200));
    await placeMarker(page, 816, 463);
    await page.mouse.click(816, 463);
})();
let enableMarkerPlacement = false;
// 封装的放置标记的函数
async function placeMarker(page, x, y) {
    if (enableMarkerPlacement) {
        await page.evaluate(({ x, y }) => {
            const marker = document.createElement('div');
            marker.style.width = '10px';
            marker.style.height = '10px';
            marker.style.background = 'red';
            marker.style.position = 'absolute';
            marker.style.top = `${y}px`;
            marker.style.left = `${x}px`;
            marker.style.zIndex = '10000';
            marker.style.borderRadius = '50%';
            document.body.appendChild(marker);
        }, { x, y });
    }
}

因为jumpserver点击具体工具后的界面是canvas,没有界面元素,所以只能按位置进行点击,所以这个代码在不同的电脑可能还运行不了相同的效果。但其提供了一种思路,其它人要模仿,这里唯一的问题点是如何获取我在界面上要点击的座标?

关于这点,做前端的应该比较熟,我这里提供一种方法,直接打开浏览器,按F12,打开console标签,里面输入

json 复制代码
document.addEventListener('mousemove', (event) => {
    console.log(`Mouse X: ${event.clientX}, Mouse Y: ${event.clientY}`);
});

接下来你鼠标移动到哪里,console都会显示当前鼠标的座标,这样你就可以估算canvas你要点击的按钮的座标位置了。

在写代码期间可以把enableMarkerPlacement参数改为true,它会显示模拟点击的座标位置,画个小红点,不至于摸不着头脑不知道自己是否真的点击了

抛砖引玉,各位大神给出你们的离谱用法吧~

相关推荐
TangAcrab14 小时前
puppeteer 爬虫初探
puppeteer·puppeteer 爬虫
Dsw_FE1 个月前
应用node Puppeteer爬取数据
爬虫·puppeteer
struggle_coder1 个月前
【Could not find Chrome This can occur if either】
前端·chrome·node·puppeteer
阿莫、2 个月前
Puppeteer的基本使用及多目标同时访问
node.js·express·puppeteer
JuneRain3 个月前
从一个接口请求全过程分析网页性能指标
javascript·puppeteer
车家大少爷3 个月前
centos node puppeteer chrome报错问题
chrome·centos·node·puppeteer
垂慕容3 个月前
puppeteer 自动化检测常用 API (第三弹)
puppeteer
垂慕容3 个月前
puppeteer 自动化检测常用 API (第一弹)
puppeteer
垂慕容3 个月前
puppeteer 自动化检测常用 API (第二弹)
puppeteer
程序员也要学好英语3 个月前
puppeteer疑难杂症解决记录
puppeteer