使用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&¤tUrl.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页面遍历的资料请关注脚本之家其它相关文章!