node.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > node.js > Puppeteer页面遍历

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

作者:日拱一車

很多时候我们需要遍历我们的页面来检查页面是否存在问题,以更好的保证可用性和安全性,下面就来讲讲如何使用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页面遍历的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文