Phantomjs、Selenium之后浪Puppeteer

网友投稿 732 2022-05-29

随着PhantomJS的bug越来越多,也无人维护后,谷歌推出的Puppeteer已达60Kstar,替代是毫无疑问。如果不考虑浏览器兼容问题,Puppeteer的简洁的接口,更简单的Js语法,做自动化测试也是不错的方案。

Puppeteer是什么?

Phantomjs、Selenium之后浪Puppeteer

Puppeteer官网:https://pptr.dev/ 建议FQ访问。

Github地址:https://github.com/puppeteer/puppeteer

Puppeteer是一个Node库,它提供了高级API来通过DevTools协议控制Chrome或Chromium,简单理解成我们日常使用的Chrome的无界面版本,可以使用js接口进行进行操控。意味凡是Chrome浏览器能干的事情,Puppeteer都能出色的完成,比如:

生成页面的屏幕截图和PDF。

爬取SPA(单页应用程序)并生成预渲染的内容(即“ SSR”(服务器端渲染)),能抓取到所有能在页面正常渲染的内容,无论是html还是基于js的异步加载。

自动执行表单提交,UI测试,键盘输入,模拟用户登录等。

创建最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试。

捕获时间线跟踪 您的网站以帮助诊断性能问题。

测试Chrome扩展程序。

安装Puuueteer

依赖npm,建议使用cnpmnpm i puppeteer或者yarn add puppeteer

安装好后,会自动安装Chromium,大约100多M,目前puppeteer的版本已到3.0.2。

Puppeteer API结构

Puppeteer API是分层的,和浏览器保持一致,如图所示(褪色实体当前未在Puppeteer中表示):

Puppeteer API结构

Puppeteer使用DevTools协议与浏览器通信.

Browser 实例可以拥有多个浏览器上下文。

BrowserContext 实例定义了一个浏览会话,并且可以拥有多个页面。

Page至少有一个框架:主框架。iframe可能还会创建其他框架或框架 标签。

Frame具有至少一个执行上下文-默认执行上下文-在其中执行框架的JavaScript。框架可能具有与扩展关联的其他执行上下文.

Worker具有单个执行上下文,并有助于与WebWorkers进行交互.

Puppeteer 入门教程和实践

async/await语法

Puppeteer 官方推荐的是使用高版本 Node 的 async/await 语法

const puppeteer = require('puppeteer'); (async () => {   const browser = await puppeteer.launch();   const page = await browser.newPage();   await page.goto('https://www.baidu.com'); //打开一个网页   // 执行其他脚步...   await browser.close(); })();

网站截图:

const puppeteer = require('puppeteer');  const iPhone = puppeteer.devices['iPhone 8']; //指定为手机端  (async () => {    //const browser = await puppeteer.launch();    const browser = await puppeteer.launch({      headless: false //可以看到打开浏览器效果,默认值true    });      const page = await browser.newPage();    await page.emulate(iPhone);    await page.goto('https://www.baidu.com');    //quality 指定照片质量0-100,不支持png格式图片    await page.screenshot({        path: 'baidu.jpg',        quality: 100,        fullPage: true    });    await browser.close();  })();

生成PDF:

const puppeteer = require('puppeteer');   (async () => {     const browser = await puppeteer.launch();     const page = await browser.newPage();     //waitUntil:networkidle2 会一直等待,直到页面加载后同时没有存在 2 个以上的资源请求,这个种状态持续至少 500 ms     await page.goto('https://www.baidu.com', {waitUntil: 'networkidle2'});     await page.pdf({path: 'baidu.pdf', format: 'A4'});     await browser.close();   })();

测试Chrome扩展程序:

Chrome / Chromium中的扩展程序当前仅在non-headless模式下工作

const puppeteer = require('puppeteer'); (async () => {   const pathToExtension = require('path').join(__dirname, 'my-extension');   const browser = await puppeteer.launch({     headless: false,     args: [       `--disable-extensions-except=${pathToExtension}`,       `--load-extension=${pathToExtension}`     ]   });   const targets = await browser.targets();   const backgroundPageTarget = targets.find(target => target.type() === 'background_page');   const backgroundPage = await backgroundPageTarget.page();   // Test the background page as you would any other page.   await browser.close(); })();

高级版抓图淘宝网站

const puppeteer = require('puppeteer');  (async() => {    // 启动Chromium    const browser = await puppeteer.launch({      ignoreHTTPSErrors: true,      headless: false,      args: ['--no-sandbox']    });    // 打开新页面    const page = await browser.newPage();    // 设置页面分辨率    await page.setViewport({      width: 1920,      height: 1080    });  let request_url = 'https://www.taobao.com';    // 访问    await page.goto(request_url, {      waitUntil: 'domcontentloaded'    }).catch(err => console.log(err));    await page.waitFor(1000);    let title = await page.title();    console.log(title);  // 网页加载最大高度    const max_height_px = 20000;    // 滚动高度    let scrollStep = 1080;    let height_limit = false;    let mValues = {      'scrollEnable': true,      'height_limit': height_limit    };  while (mValues.scrollEnable) {  mValues = await page.evaluate((scrollStep, max_height_px, height_limit) =>{  if (document.scrollingElement) {      let scrollTop = document.scrollingElement.scrollTop;      document.scrollingElement.scrollTop = scrollTop + scrollStep; if (null != document.body && document.body.clientHeight > max_height_px) {   height_limit = true; } else if (document.scrollingElement.scrollTop + scrollStep > max_height_px) {   height_limit = true; } let scrollEnableFlag = false; if (null != document.body) {   scrollEnableFlag = document.body.clientHeight > scrollTop + 1081 && !height_limit; } else {   scrollEnableFlag = document.scrollingElement.scrollTop + scrollStep > scrollTop + 1081 && !height_limit; } return {   'scrollEnable': scrollEnableFlag,   'height_limit': height_limit,   'document_scrolling_Element_scrollTop': document.scrollingElement.scrollTop };  }  },  scrollStep, max_height_px, height_limit);      await sleep(800);    }  try {      await page.screenshot({        path: "taobao1.jpg",        quality: 10,        fullPage: true      }).catch(err => {        console.log('截图失败');        console.log(err);      });      await page.waitFor(5000);  } catch (e) {      console.log('执行异常');    } finally {      await browser.close();    }  })();  //延时函数  function sleep(delay) {    return new Promise((resolve, reject) => {      setTimeout(() => {        try {          resolve(1)        } catch (e) {          reject(0)        }      }, delay)    })  }

selenium

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:支付宝移动端动态化方案实践
下一篇:初识ElastricSearch
相关文章