Headless Chrome 踩坑之旅无标题文章

4月13号,phantomJS 的主要维护者突然宣布不干了,当时我正在为如何把前端代码运行到后端发愁,正想着用用 phantomJS 的时候,出了这档子事。仔细看看他说的,大意是 google 也来插一脚了,更稳定,更牛,那我就功成身退啦。好吧,感谢辛劳付出,我看看 google 到底整了啥幺蛾子。

chrome 在 59 的版本中做了一个 headless 模式,可以在这里查看原文。大致的功能就是能在服务器跑一个 chrome 浏览器,具有 chrome 的绝大部分功能。Amazing!!!这下子都不用模拟浏览器环境了,直接就整了一个浏览器的环境,值得折腾一下。

然后,我就落入了一个深基坑。。。。废话少说,直接告诉大家如何开玩。


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 啦。
最后的网址随意填写,我在这写的是我们的产品—— 石墨文档
随意打开一个浏览器,输入 http://localhost:9222 可以得到如下的效果

Headless Chrome 踩坑之旅无标题文章_第1张图片

看到这个就证明,你成功开启了 headless chrome 的服务

3.调用 chrome

调用 Chrome 需要用到一个 node 模块——chrome-remote-interface
官网的例子足够本地测试使用,我们团队在实际使用过程中发现了不少坑。

第一个坑是远程连接,CDP 中提供了 remote 的配置来允许你远程连接 Chrome,笔者第一次使用时,就遇上了一个 bug,Headless Chrome 还没有完美对接,我刚想着给作者提一个 bug。


Headless Chrome 踩坑之旅无标题文章_第2张图片

作者立马修了。。。。。为他点赞,但是在实际使用过程中,还是需要设置好 nginx 的反向代理

第二个坑则是协议 (protocol),这个协议决定你能用什么接口去调用 chrome 的服务,具体的 API 在这里。如何获得协议?参见源码,因为总所周知的原因,下载协议很慢,大家先下载下来,然后在 protocol 的选项里写上
protocol: JSON.parse(fs.readFileSync('protocol.json'))

就可以了。
ps: 作者说可以用
chrome-remote-interface protocol -r > protocol.json

这个命令生成协议,但是我生成的是一个错误的文件。。。。

本地的连接调试非常简单,如果你想远程调用的话,需要这样子设置

'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,有兴趣的同学可以和我们石墨团队深入浅出的交流一下。

你可能感兴趣的:(Headless Chrome 踩坑之旅无标题文章)