技能樹升級——Chrome Headless模式

做者:Jogis
原文連接:https://github.com/yesvods/Bl...
轉載請註明原文連接以及做者信息css

也許最近已經據說Chrome59將支持headless模式,PhantomJS核心開發者Vitaly表示本身將會失業了。html

Headless模式解決了什麼問題

3年前,無頭瀏覽器PhantomJS已經如火如荼出現了,緊跟着NightmareJS也成爲一名巨星。無頭瀏覽器帶來巨大便利性:頁面爬蟲、自動化測試、WebAutomation...前端

爲啥Chrome又插了一腳

用過PhantomJS的都知道,它的環境是運行在一個封閉的沙盒裏面,在環境內外徹底不可通訊,包括API、變量、全局方法調用等。一個以前寫的微信頁面爬蟲,實現內外通訊的方式極其Hack,爲了達到目的,不擇手段,使人髮指,看過的哥們都會蛋疼。node

So, 很天然的,Chrome59版支持的特性,所有能夠利用,簡直不要太爽:git

  • ES2017github

  • ServiceWork(PWA測試隨便耍)chrome

  • 無沙盒環境npm

  • 無痛通信&API調用數組

  • 無與倫比的速度瀏覽器

  • ...

技能樹啓動點

爲了點亮技能樹,咱們須要如下配置:

大體來講,有那麼個過程:

啓動Headless模式

有各類腳本啓動方式,本次咱們使用termial參數方式來打開:

$ /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222

在Dock中,一個黃色的東西就會被啓動,可是他不會跳出來。

操控無頭瀏覽器

依舊有各類方式,咱們先安裝一個工具幫助咱們來對黃色瀏覽器作點事情:

$ tnpm i -S chrome-remote-interface

燥起來

捕獲全部請求

Pretty Simple,寫一個index.js:

const CDP = require("chrome-remote-interface");
 
CDP(client => {
  // extract domains
  const { Network, Page } = client;
  // setup handlers
  Network.requestWillBeSent(params => {
    console.log(params.request.url);
  });
  Page.loadEventFired(() => {
    client.close();
  });
  // enable events then start!
  Promise.all([Network.enable(), Page.enable()])
    .then(() => {
      return Page.navigate({ url: "https://github.com" });
    })
    .catch(err => {
      console.error(err);
      client.close();
    });
}).on("error", err => {
  // cannot connect to the remote endpoint
  console.error(err);
});

AND run it:

$ node index.js

結果會展現一堆url:

https://github.com/
https://assets-cdn.github.com/assets/frameworks-12d63ce1986bd7fdb5a3f4d944c920cfb75982c70bc7f75672f75dc7b0a5d7c3.css
https://assets-cdn.github.com/assets/github-2826bd4c6eb7572d3a3e9774d7efe010d8de09ea7e2a559fa4019baeacf43f83.css
https://assets-cdn.github.com/assets/site-f4fa6ace91e5f0fabb47e8405e5ecf6a9815949cd3958338f6578e626cd443d7.css
https://assets-cdn.github.com/images/modules/site/home-illo-conversation.svg
https://assets-cdn.github.com/images/modules/site/home-illo-chaos.svg
https://assets-cdn.github.com/images/modules/site/home-illo-business.svg
https://assets-cdn.github.com/images/modules/site/integrators/slackhq.png
https://assets-cdn.github.com/images/modules/site/integrators/zenhubio.png
https://assets-cdn.github.com/assets/compat-8a4318ffea09a0cdb8214b76cf2926b9f6a0ced318a317bed419db19214c690d.js
https://assets-cdn.github.com/static/fonts/roboto/roboto-medium.woff
...

捕獲DOM內全部圖片

此次輪到演示一下如何操控DOM:

const CDP = require("chrome-remote-interface");
 
CDP(chrome => {
  chrome.Page
    .enable()
    .then(() => {
      return chrome.Page.navigate({ url: "https://github.com" });
    })
    .then(() => {
      chrome.DOM.getDocument((error, params) => {
        if (error) {
          console.error(params);
          return;
        }
        const options = {
          nodeId: params.root.nodeId,
          selector: "img"
        };
        chrome.DOM.querySelectorAll(options, (error, params) => {
          if (error) {
            console.error(params);
            return;
          }
          params.nodeIds.forEach(nodeId => {
            const options = {
              nodeId: nodeId
            };
            chrome.DOM.getAttributes(options, (error, params) => {
              if (error) {
                console.error(params);
                return;
              }
              console.log(params.attributes);
            });
          });
        });
      });
    });
}).on("error", err => {
  console.error(err);
});

最後會返回數組,看起來像醬紫:

[
  [ 'src',
    'https://assets-cdn.github.com/images/modules/site/home-illo-conversation.svg',
    'alt',
    '',
    'width',
    '360',
    'class',
    'd-block width-fit mx-auto' ]
  [ 'src',
    'https://assets-cdn.github.com/images/modules/site/home-illo-chaos.svg',
    'alt',
    '',
    'class',
    'd-block width-fit mx-auto' ]
  [ 'src',
    'https://assets-cdn.github.com/images/modules/site/home-illo-business.svg',
    'alt',
    '',
    'class',
    'd-block width-fit mx-auto mb-4' ]
    ...
]

chrome-remote-interface 提供一套完整的API用於利用全量Chrome特性,更多使用方法參考:https://github.com/cyrus-and/...

總結

Chrome Headless特性,不單單革新了原有格局,並且提升開發效率,下降使用門檻,對於常常使用爬蟲、自動化測試前端童鞋來講簡直是巨大福音,對於新童鞋來講也是一個新潮的玩具。

相關文章
相關標籤/搜索