zoukankan      html  css  js  c++  java
  • 关于Puppeteer的那些事儿

    原文:https://www.cnblogs.com/zlforever-young/p/11594211.html

    最近开始上手一个自动化测试工具Puppeteer,来谈一谈关于它的一些事儿。

    Puppeteer中文文档:https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=v1.20.0&show=api-class-puppeteer(推荐看完预热视频后再读API)

    Puppeteer官方文档:https://github.com/GoogleChrome/puppeteer

    预热视频:https://www.youtube.com/watch?v=IvaJ5n5xFqU    以及     https://www.youtube.com/watch?v=ARt3zDHSsd4

    在线编写测试网站:https://try-puppeteer.appspot.com/

    puppeteer社区:https://slack.com/

    √安装

    安装puppeteer

    cnpm i puppeteer

    安装puppeteer-core

    cnpm i puppeteer-core

    √常用方法或属性:

    1. puppeteer.launch([options])

    复制代码
    //Puppeteer 模块提供了一种启动 Chromium 实例的方法。 下面就是使用 Puppeteer 进行自动化的一个典型示例:
    const puppeteer = require('puppeteer');
    
    puppeteer.launch().then(async browser => {
      const page = await browser.newPage();
      await page.goto('https://www.google.com');
      // 其他操作...
      await browser.close();
    });
    复制代码

    2.Browser 

    当 Puppeteer 连接到一个 Chromium 实例的时候会通过 puppeteer.launch 或 puppeteer.connect 创建一个 Browser 对象。

    复制代码
    //下面是使用 Browser 创建 Page 的例子
    const puppeteer = require('puppeteer');
    
    puppeteer.launch().then(async browser => {
      // 存储节点以便能重新连接到 Chromium
      const browserWSEndpoint = browser.wsEndpoint();
      // 从 Chromium 断开和 puppeteer 的连接
      browser.disconnect();
    
      // 使用节点来重新建立连接
      const browser2 = await puppeteer.connect({browserWSEndpoint});
      // 关闭 Chromium
      await browser2.close();
    });
    复制代码
    复制代码
    //一个断开连接和重连到 Browser 的例子:
    const puppeteer = require('puppeteer');
    
    puppeteer.launch().then(async browser => {
      // 存储节点以便能重新连接到 Chromium
      const browserWSEndpoint = browser.wsEndpoint();
      // 从 Chromium 断开和 puppeteer 的连接
      browser.disconnect();
    
      // 使用节点来重新建立连接
      const browser2 = await puppeteer.connect({browserWSEndpoint});
      // 关闭 Chromium
      await browser2.close();
    });
    复制代码

     3.Page

    Page 提供操作一个 tab 页或者 extension background page 的方法。一个 Browser 实例可以有多个 Page 实例。

    下面的例子创建一个 Page 实例,导航到一个 url ,然后保存截图:

    复制代码
    const puppeteer = require('puppeteer');
    
    puppeteer.launch().then(async browser => {
      const page = await browser.newPage();
      await page.goto('https://example.com');
      await page.screenshot({path: 'screenshot.png'});
      await browser.close();
    });
    复制代码

    4.Keyboard 

    Keyboard 提供一个接口来管理虚拟键盘. 高级接口为 keyboard.type, 其接收原始字符, 然后在你的页面上生成对应的 keydown, keypress/input, 和  keyup 事件.

    为了更精细的控制(虚拟键盘), 你可以使用 keyboard.down, keyboard.up 和 keyboard.sendCharacter 来手动触发事件, 就好像这些事件是由真实的键盘生成的.

    复制代码
    //持续按下 Shift 来选择一些字符串并且删除的例子:

    await page.keyboard.type('Hello World!'); await page.keyboard.press('ArrowLeft'); await page.keyboard.down('Shift'); for (let i = 0; i < ' World'.length; i++) await page.keyboard.press('ArrowLeft'); await page.keyboard.up('Shift'); await page.keyboard.press('Backspace'); // 结果字符串最终为 'Hello!'
    复制代码
    //按下A的例子
    await page.keyboard.down('Shift');
    await page.keyboard.press('KeyA');
    await page.keyboard.up('Shift');

     5. Mouse 

    Mouse 类在相对于视口左上角的主框架 CSS 像素中运行。

    每个 page 对象都有它自己的 Mouse 对象,使用见 page.mouse。

    复制代码
    // 使用 ‘page.mouse’ 追踪 100x100 的矩形。
    await page.mouse.move(0, 0);
    await page.mouse.down();
    await page.mouse.move(0, 100);
    await page.mouse.move(100, 100);
    await page.mouse.move(100, 0);
    await page.mouse.move(0, 0);
    await page.mouse.up();
    复制代码

     更多方法和属性请阅读官网

     

    √实战01:跳转指定页面

    源码:跳转到百度首页

    复制代码
    const puppeteer=require('puppeteer');
    
    (async ()=>{
    
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page=  await browser.newPage();
        await page.goto("https://www.baidu.com");
    
    })();
    复制代码

    效果:

     

    √实战02:输入文本与元素点击

    代码:在百度中搜索

    复制代码
    const puppeteer=require('puppeteer');
    
    (async ()=>{
    
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page=  await browser.newPage();
        await page.goto("https://www.baidu.com");  //跳转页面
        const input_text= await page.$("#kw");     //获取百度首页的搜索框。page.$()用来查找元素
        await input_text.type("Hello Word!");      //type()输入内容
        const btn_click=await page.$("#su");       //获取百度首页的搜索按钮。
        await btn_click.click();                   //点击搜索按钮。
    
    })();
    复制代码

    效果:

    √实战03:获取文本元素值

    源码:获取百度词条的值

    复制代码
    const puppeteer=require('puppeteer');
    
    (async ()=>{
    
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page=  await browser.newPage();
        await page.goto("https://www.baidu.com");  //跳转页面
        const input_text= await page.$("#kw");     //获取百度首页的搜索框。page.$()用来查找元素
        await input_text.type("Hello Word!");      //type()输入内容
        const btn_click=await page.$("#su");       //获取百度首页的搜索按钮。
        await btn_click.click();                  //点击搜索按钮。
    
        await page.waitFor('div#content_left > .result-op.c-container.xpath-log',{visible:true});//由于获取元素是异步操作,需要等待该元素加载出来
    
        let resultText= await page.$eval('div#content_left > .result-op.c-container.xpath-log',ele=>{return ele.innerHTML})//获取元素并返回元素下的innerHTML。 .$eval表示获取单个元素
        console.log("result is ",resultText);//在控制台打印出值。
    
    })();
    复制代码

    演示:

    √实战04:puppeteer文件上传操作

    代码:在百度首页上传图片

    复制代码
    const puppeteer=require('puppeteer');
    
    (async ()=>{
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page = await browser.newPage();
        await page.goto('https://www.baidu.com');
    
        await page.waitForSelector('span.soutu-btn');  //等待选择元素出现
        const soutuBtn=await page.$('span.soutu-btn'); //获取图片按钮
        await soutuBtn.click();                        //点击展开图片按钮
    
        await page.waitForSelector('input.upload-pic');   //等待上传按钮出现
        const uploadPic=await page.$('input.upload-pic'); //获取上传按钮
        await uploadPic.uploadFile('C:\Capture.PNG');    //上传图片。注意:路径要用双斜杠。
    })();
    复制代码

    演示:

    √实战05:puppeteer处理多个元素

    代码:打印京东上的手机信息

    复制代码
    const puppeteer = require('puppeteer');
    
    (async()=>{
        const browser=await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page =await browser.newPage();
        await page.goto('https://www.jd.com');
    
        await page.waitFor("#key");
        const inputText=await page.$("#key");
        await inputText.type("手机");
        await page.keyboard.press('Enter');
    
        await page.waitForSelector("ul.gl-warp > li");
        const items=await page.$$eval("ul.gl-warp > li",eles=>eles.map(ele=>ele.innerText));
        console.log("手机列表=",items);
    })();
    复制代码

    演示:

     

    √实战06:puppeteer切换iframe进行操作

     iframe跟page的用法类似。使用前需要切换到iframe里面并用src定位要操作的iframe。操作可参考:https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#class-frame

    代码:自动在阿里云的注册iframe里面填写注册信息

    复制代码
    const puppeteer = require('puppeteer');
    
    (async()=>{
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800}});
        const page = await browser.newPage();
        await page.goto("https://account.aliyun.com/register/register.html");
    
        //切换iframe
        const frame= await page.frames().find(frame=>frame.url().includes("https://passport.aliyun.com"));//切换iframe,并找到对应src的iframe
        await frame.waitFor("input#nick"); //等待输入框加载完成
        const nick =await frame.$("input#nick");//获取输入框
        await nick.type("测试用户");//输入数据
        
    })();
    复制代码

    演示:

    √实战07:puppeteer拖拽操作阿里云验证码

    代码:自动操作阿里云验证滑动模块

    复制代码
    const puppeteer = require('puppeteer');
    
    (async()=>{
        const browser = await puppeteer.launch({headless:false,defaultViewport:{1000,height:800},ignoreDefaultArgs:["--enable-automation"]});//在有些页面可能需要将automation提示去掉。使用ignoreDefaultArgs:["--enable-automation"]参数
        const page = await browser.newPage();
        await page.goto("https://account.aliyun.com/register/register.html");
    
        //切换iframe
        const frame= await page.frames().find(frame=>frame.url().includes("https://passport.aliyun.com"));//切换iframe,并找到对应src的iframe
        await frame.waitForSelector("span#nc_1_n1z");//等待滑动块加载完成
        const span =await frame.$("span#nc_1_n1z");  //获取滑动元素
        const spanInfo=await span.boundingBox();     //获取滑动块的信息,包括位置(x,y)以及宽和高
        //console.log(spanInfo);
    
        await frame.waitForSelector("div#nc_1_n1t"); //等待包裹滑块的div加载完成
        const outDiv=await frame.$("div#nc_1_n1t");  //获取包裹滑块的div
        const outDivInfo=await outDiv.boundingBox(); //获取包裹滑块的div的信息,包括位置(x,y)以及宽和高
        //console.log(outDivInfo);
    
        await page.mouse.move(spanInfo.x,spanInfo.y);//将鼠标移动到滑块位置
        await page.mouse.down();                     //将鼠标按下(默认是左键)
        for(var i=0;i<outDivInfo.width;i++){
            page.mouse.move(spanInfo.x+i,spanInfo.y);//让鼠标向左移动outDivInfo的宽度距离
        }
        await page.mouse.up();                       //将鼠标松开
     
    })();
    复制代码

    演示:

    √实战08:puppeteer自动抓取百度新闻上的语句并自动登录微博账户发一条微博

     代码:这个实战似乎翻车了,被微博检测到自动化而被要求输入验证码

    复制代码
    const puppeteer = require('puppeteer');
    const config=require('./config'); //为了保护我的个人隐私,所以我把账号和密码保存在了config文件中
    
    (async ()=>{
        // console.log(config.username);
        // console.log(config.password);
        const browser = await puppeteer.launch({
            headless:false,
            defaultViewport:{1280,height:800},
            ignoreDefaultArgs:["--enable-automation"],//移除自动化,防止页面生成验证码
            slowMo:200,//输入延迟时间
            args:['--window-size:1280,800'],//调整窗口大小
            
        });
        const page= await browser.newPage();
        await page.goto('https://news.baidu.com/',{waitUntil:"networkidle2"});//第一个参数是要前往的地址url,第二个参数是保证页面全部加载
    
        await page.waitForSelector('#imgTitle>a>strong');
        const newsText=await page.$eval("#imgTitle>a>strong",ele=>ele.innerText);//匹配第一个元素
        // console.log(newsText);
    
        await page.goto('https://weibo.com',{waitUntil:"networkidle2"});
        await page.waitFor(5*1000);//防止被检测
        await page.reload();//防止被检测
    
        await page.waitForSelector('#loginname');                   //等待账号输入框加载完成
        const inputText=await page.$('#loginname');                 //获取账号输入框元素
        await inputText.click();                                    //防止被检测,具体情况具体分析
        await inputText.type(config.username);
    
        await page.waitForSelector('input[name="password"]');       //等待密码输入框加载完成
        const inputPwd=await page.$('input[name="password"]');      //获取密码输入框
        await inputPwd.click();//防止被检测,具体情况具体分析
        await inputPwd.type(config.password);
    
    
        await page.waitForSelector('a[action-type="btn_submit"]');  //等待确认按钮加载
        const submit=await page.$('a[action-type="btn_submit"]');   //获取确认按钮
        await submit.click();                                       //点击
    
    })();
    复制代码

    演示:翻车啦!!!

    √实战09:puppeteer模拟快捷键

     代码演示:https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#class-keyboard

    √实战10:puppeteer切换浏览器tab页

    主要用到api:browser.target();

    文档:https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#class-browser

    √实战11:puppeteer处理弹出的对话框

    主要用到的api:Dialog处理弹出的内容

    文档:https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#class-dialog

    √实战12:puppeteer执行JavaScript方法

    主要用到的方法:page.evaluate(()=>{  在这里面可以写任意JS代码  })

    文档:https://github.com/GoogleChrome/puppeteer/blob/v1.20.0/docs/api.md#class-page

    √实战13:配置typescript环境,并在其中使用puppeteer

     待完善 

    √实战14:获取全屏截图

    源码:

    复制代码
    const puppeteer =require('puppeteer');//引入puppeteer
    (async()=>{//使用自执行函数
        const browser = await puppeteer.launch();//生成browser实例
    
        const page = await browser.newPage();//生成一个页面
        await page.goto('https://cn.aliyun.com/');//前往页面
    
        console.log(await page.content());//打印页面信息(源码)
        await page.screenshot({//截图
        path: 'ali.png',
        fullPage: true
        });
    
        await browser.close();//关闭browser实例
    })();
    复制代码

    效果图:

    代码执行结果

     
  • 相关阅读:
    destoon手机端mobileurl函数增加城市分类参数
    jCarousel,jQuery下的滚动切换传送插件
    jQuery plugin : bgStretcher 背景图片切换效果插件
    jquery图片切换插件jquery.cycle.js参数详解
    destoon 后台管理左侧新增菜单项
    destoon 列表页面增加手动选择排序方式
    jQuery 淡入淡出有png图的时候 ie8下有黑色边框
    java中Array和ArrayList区别
    趣味理解ADO.NET对象模型
    两个datatable的比较
  • 原文地址:https://www.cnblogs.com/cdchencw/p/13366873.html
Copyright © 2011-2022 走看看