使用Puppeteer实现页面遍历的示例代码

 更新时间:2023年06月26日 11:40:48   作者:日拱一車  
很多时候我们需要遍历我们的页面来检查页面是否存在问题,以更好的保证可用性和安全性,下面就来讲讲如何使用puppeteer来实现页面遍历的功能吧

前言

很多时候我们需要遍历我们的页面来检查页面是否存在问题,以更好的保证可用性和安全性,所以遍历一个给定页面是比较通用的能力,是很多高级功能的基础。下面就介绍怎么使用puppeteer来实现页面遍历的功能。

基本算法

实现页面的遍历功能,我们需要实现几个基础的方法,如下:

  • 怎么获取到登录态
  • 页面如何打开
  • 获取到页面的可点击节点
  • 页面的滑动,点击,截图等基础功能
  • 页面请求的拦截,识别
  • 页面返回/退出

上述能力实现之后,将他们组合起来,就可以实现一个页面的遍历功能,我们分别讲解每个功能如何实现。

功能实现

登录态

不同的帐号有不同的登录方式,最通用的就是专门写一个脚本来实现登录功能。对于需要扫码登录的页面,其实是从服务端获取登录token,可以直接调用服务端来获取(前提是你自己的业务)。否则就只能老老实实的通过脚本来实现了(在浏览器端实现脚本相对容易)。

页面打开

puppeteer提供了专门的方法来打开页面,我们只要初始化之后,调用这个功能就可以了。代码如下:

async function openUrl( targetUrl ){
    //const browser = await puppeteer.connect(config.browserLaunchOptions);
    const browser = await puppeteer.launch(config.browserLaunchOptions);
    console.log("userAgent:"+JSON.stringify(await browser.userAgent()));
    const page = await browser.newPage();
    interactor(page)
    /**
     * 开启监听页面请求数据
     */
    await setPageWatcher(page);
    await page.emulate(config.pageEmulateOptions);
    await page.goto(targetUrl, {timeout:config.timeoutMillSeconds, waitUntil: config.waitUntilStr}).catch(err => {});
    await page.waitFor(10000);
    await waitForPageComplete(page,2);
    await setBrowserWatcher(browser);
    loginPageUrl = targetUrl;
    return page;
}

获取页面的可点击点

拿到一个页面之后我们需要获取到他可点击的点位信息,以便我们后续遍历的时候操作,所以需要一个获取页面可点击点的方法。实现如下:

async function getClickableElements( targetFrame ){
    try{
        let sections = await targetFrame.$$('[data-clickable=true],.tr-tabbar-item')
        return sections;
    } catch (e) {
        console.log(e);
        return null;
    }
}

页面的滑动,点击,截图等基础功能

对于页面的滑动,点击和截图,有专门的方法来实现,代码如下:

function screenshot( page,picName ){
    return new Promise((resolve, reject) => {
        setTimeout(async () => {
            var newPage=null;
            try {
                var buf=null;
                if( newPagePromise ){
                    console.log('新开了一个页面');
                    newPage = await newPagePromise;
                    await newPage.waitFor(6000);
                    var currentUrl=await newPage.url();
                    console.log("new-Page-Url:"+currentUrl);
                    if(currentUrl&&currentUrl.includes('https://login.xxx.com/login.htm?redirectURL=')){
                       currentUrl = currentUrl.replace('https://login.xxx.com/login.htm?redirectURL=',config.loginUrl);
                       console.log("newUrl="+currentUrl);
                        await openTargetUrl(newPage,currentUrl);
                    }
                    buf = await newPage.screenshot({
                    })
                    await newPage.close();
                    newPagePromise = null;
                    await page.bringToFront();
                } else {
                    buf = await page.screenshot({
                    })
                }
                if(buf){
                    console.log('截图完成,开始上传');
                    var picUrl =await util.uploadImageWithRetry(picName,buf);
                    console.log("截图成功:"+picUrl);
                    resolve(picUrl)
                }
                resolve(null);
            } catch (e) {
                if (newPage) {
                    await newPage.close();
                }
                newPagePromise = null;
                await page.bringToFront();
                console.log(e);
                reject(null)
            }
        })
    })
}
// 元素点击
await element.tap(2000);

页面请求的拦截,识别

在执行过程中页面可能出现跳转,并且我们还需要监听页面的请求来检查是不是正常。实现如下:

function setPageWatcher(page) {
    page.on('requestfailed', error => {
       if(error.url()&&error.url().includes('https://login.xxx.com')){
           console.log("跳转到了登录页面:"+error);
           needReLogin = true;
       }
    })
    page.on('error', (error) => {
        //console.log(chalk.red('💢 whoops! there was an error'))
        //console.log(error)
    })
    page.on('pageerror', (error) => {
        //console.log(error)
    })
    page.on('response',(response) => {
        if( "image"==response.request().resourceType() && response.url() && response.headers()['content-length'] && response.headers()['content-length'] >200 ){
            allResource.push({
                size: response.headers()['content-length'],
                type: response.request().resourceType(),
                url: response.url()
            });
        }
    })
    page.on('dialog', async dialog => {
        console.log("dialog");
        await dialog.accept();
        console.log(dialog.message());
        //await dialog.dismiss();
    });
}

页面返回/退出

代码如下:

function pageBack( page, frameInfo,num ){
​​​​​​​     console.log("开始回到首页");
     return new Promise((resolve, reject) => {
         setTimeout(async () => {
             try {
                 let backIcons = await frameInfo.backIconFrame.$$('.backIcon');
                 if(backIcons.length>0&&!needReLogin){
                     try{
                         console.log("回到首页");
                         await backIcons[0].tap(2000);
                         await page.waitFor(2000);
                         resolve(frameInfo);
                     }catch (e) {
                         resolve(reloadPage(page,num));
                     }
                 } else {
                     resolve(reloadPage(page,num));
                 }
             } catch (e) {
                 console.log('回到首页出错!',e);
                 resolve(reloadPage(page,num))
             }
         })
     })
}

以上基本功能就实现了,欢迎交流

以上就是使用Puppeteer实现页面遍历的示例代码的详细内容,更多关于Puppeteer页面遍历的资料请关注脚本之家其它相关文章!

相关文章

  • Node.js中fs模块实现配置文件的读写操作

    Node.js中fs模块实现配置文件的读写操作

    在Node.js中, fs模块提供了对文件系统的访问功能,我们可以利用它来实现配置文件的读取和写入操作,这篇文章主要介绍了Node.js中fs模块实现配置文件的读写,需要的朋友可以参考下
    2024-04-04
  • 如何使用puppet替换文件中的string

    如何使用puppet替换文件中的string

    今天小编就为大家分享一篇关于如何使用puppet替换文件中的string,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 利用node.js搭建简单web服务器的方法教程

    利用node.js搭建简单web服务器的方法教程

    本文主题是使用node来搭建最简单的web服务器,其后可以自己根据需要深入了解,目前在开发过程中可以用来模拟与服务器进行简单的交互,比如返回的资源控制等。需要的朋友可以参考学习,下面来一起看看吧。
    2017-02-02
  • Vue+Node服务器查询Mongo数据库及页面数据传递操作实例分析

    Vue+Node服务器查询Mongo数据库及页面数据传递操作实例分析

    这篇文章主要介绍了Vue+Node服务器查询Mongo数据库及页面数据传递操作,结合实例形式分析了node.js查询MongoDB数据库及vue前台页面渲染等相关操作技巧,需要的朋友可以参考下
    2019-12-12
  • nodejs对express中next函数的一些理解

    nodejs对express中next函数的一些理解

    这篇文章主要介绍了nodejs对express中next函数的一些理解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • 使用Node.js实现base64和png文件相互转换的方法

    使用Node.js实现base64和png文件相互转换的方法

    这篇文章主要介绍了使用Node.js实现base64和png文件相互转换的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 带你了解NodeJS事件循环

    带你了解NodeJS事件循环

    这篇文章主要介绍NodeJS事件循环,Node中代码从上到下同步执行,在执行过程中会将不同的任务添加到相应的队列中,那具体有的循环又是怎么回事呢,限免现编就带大家学习该详细内容,需要的朋友也可以参考一下
    2022-02-02
  • node.js使用express-fileupload中间件实现文件上传

    node.js使用express-fileupload中间件实现文件上传

    本文使用express作为服务端,使用express-fileupload库提供的中间件函数来接受从客户端传来的图片,并将图片作为文件存储在服务端,感兴趣的可以了解一下
    2021-07-07
  • nodejs获取微信小程序带参数二维码实现代码

    nodejs获取微信小程序带参数二维码实现代码

    这篇文章主要介绍了nodejs获取微信小程序带参数二维码实现代码的相关资料,需要的朋友可以参考下
    2017-04-04
  • 一文详解如何在IDEA中配置Node.js

    一文详解如何在IDEA中配置Node.js

    idea中支持运行很多种编程语言,只需要在电脑中安装好对应的语言环境,下面这篇文章主要给大家介绍了关于如何在IDEA中配置Node.js的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-02-02

最新评论