4月13號铸豁,phantomJS 的主要維護者突然宣布不干了头镊,當時我正在為如何把前端代碼運行到后端發(fā)愁,正想著用用 phantomJS 的時候魄幕,出了這檔子事相艇。仔細看看他說的,大意是 google 也來插一腳了纯陨,更穩(wěn)定坛芽,更牛,那我就功成身退啦翼抠。好吧咙轩,感謝辛勞付出,我看看 google 到底整了啥幺蛾子阴颖。
chrome 在 59 的版本中做了一個 headless 模式臭墨,可以在這里查看原文。大致的功能就是能在服務器跑一個 chrome 瀏覽器膘盖,具有 chrome 的絕大部分功能胧弛。Amazing!O琅稀结缚!這下子都不用模擬瀏覽器環(huán)境了,直接就整了一個瀏覽器的環(huán)境软棺,值得折騰一下红竭。
然后,我就落入了一個深基坑。茵宪。最冰。。廢話少說稀火,直接告訴大家如何開玩暖哨。
1.準備 Chrome
首先,你需要一個支持 Headless 模式的 Chrome凰狞。
Linux 平臺請安裝最新的 dev 版本篇裁,macOS 平臺請安裝最新的 金絲雀 版本,Win 平臺赡若,我還沒試過达布,知道的朋友可以分享一下。
2.運行 headless chrome
安裝好之后逾冬,運行如下命令:
Linux:
google-chrome-unstable --headless --remote-debugging-port=9222 --disable-gpu https://shimo.im
macOS:
/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --headless --remote-debugging-port=9222 https://shimo.im/
--headless 就是開啟 headless 模式黍聂。
--remote-debugging-port=9222 這是開啟 Chrome 的端口是 9222,這樣子 Chrome 就類似于微服務一樣啦身腻。
--disable-gpu 不使用 gpu分冈,既然是在后端運行的 Chrome 當然不需要 gpu 啦。
最后的網(wǎng)址隨意填寫霸株,我在這寫的是我們的產(chǎn)品—— 石墨文檔
隨意打開一個瀏覽器,輸入 http://localhost:9222 可以得到如下的效果
看到這個就證明集乔,你成功開啟了 headless chrome 的服務
3.調用 chrome
調用 Chrome 需要用到一個 node 模塊——chrome-remote-interface
官網(wǎng)的例子足夠本地測試使用去件,我們團隊在實際使用過程中發(fā)現(xiàn)了不少坑。
第一個坑是遠程連接扰路,CDP 中提供了 remote 的配置來允許你遠程連接 Chrome尤溜,筆者第一次使用時,就遇上了一個 bug汗唱,Headless Chrome 還沒有完美對接宫莱,我剛想著給作者提一個 bug。
作者立馬修了哩罪。授霸。。际插。碘耳。為他點贊,但是在實際使用過程中框弛,還是需要設置好 nginx 的反向代理
第二個坑則是協(xié)議 (protocol)辛辨,這個協(xié)議決定你能用什么接口去調用 chrome 的服務,具體的 API 在這里。如何獲得協(xié)議斗搞?參見源碼指攒,因為總所周知的原因,下載協(xié)議很慢僻焚,大家先下載下來允悦,然后在 protocol 的選項里寫上
protocol: JSON.parse(fs.readFileSync('protocol.json'))
就可以了。
ps: 作者說可以用
chrome-remote-interface protocol -r > protocol.json
這個命令生成協(xié)議溅呢,但是我生成的是一個錯誤的文件澡屡。。咐旧。驶鹉。
本地的連接調試非常簡單,如果你想遠程調用的話铣墨,需要這樣子設置
'use strict';
const CDP = require('chrome-remote-interface');
const fs = require('fs');
const protocol = JSON.parse(fs.readFileSync('protocol.json'));
const
options = {
host: "[https://chrome.com](https://chrome.com/)", // 域名或者 IP 都行
port: 443, // 按照實際情況來
remote: true, // 遠程連接需要設置為 true
protocol, // client 可以使用的方法
secure: true // https 的話需要這是這個
};
function *test() {
const client = yield CDP(options);
console.log('success!');
client.close();
}
client 提供了非常多的接口室埋,比如操作頁面的 Page,有興趣的同學可以和我們石墨團隊深入淺出的交流一下。