whilefor/blog

Chrome Headless 模式

whilefor opened this issue · 0 comments

Chrome Headless 模式

前言 Headless Browser

Headless Browser的定义是无界面的浏览器。多用于测试web应用,自动截图,测试js代码,爬虫抓取信息等等。
简而言之,现代浏览器是给用户使用,而Headless Browser则更多的是给程序使用。

Chrome的Headless模式出来之前,其他现代浏览器也都是没有提供Headless模式。现有的Headless Browser都是基于现有的几个浏览器内核来封装开发的。


比较常见的几个Headless Browser:

  • PhantomJS - QtWebKit内核
  • SlimerJS - Gecko内核
  • TrifleJS - IE内核


因为毕竟不是真实的用户浏览器环境,使用起来还是有不少的诟病。此前一段时间研究使用过PhantomJS,功能虽然够用,不过对比在真实的浏览器里面访问的数据信息还是有所差别。


最近Chrome Headless模式的发布(虽然还是开发版本里的,不过终究会变成稳定版本的功能),使得许多使用Headless Browser的纷纷替换成了Chrome,优势不言自明。

Headless Chrome

Chrome 59 beta版本开始支持Headless mode,过不久就会是稳定版本的功能。Chrome Platform Status中有详细的每个版本新增的功能。
Headless模式可以让Chrome无界面的运行,相当于开了一个无界面的浏览器的进程,然后可以通过接口或者Chrome开发者调试工具来操作Chrome,包括加载页面、获取元数据(DOM信息等)等等,所有Chrome提供的功能都可以使用。

启动Headless模式

chrome --headless --remote-debugging-port=9222 https://chromium.org --disable-gpu

--disable-gpu ,Linux服务器一般没有GPU,所以不禁用可能会产生一些错误。

DevTools - Chrome的开发者调试工具

用正常的Chrome浏览器打开http://localhost:9222, 就能看到用开发者调试工具可以操作你正在打开的页面。

Node.js API

需要使用到一个Node.js的库,chrome-remote-interface
使用该库获取加载一个页面然后获取它的DOM信息:

const CDP = require('chrome-remote-interface');
CDP((client) => {
  // Extract used DevTools domains.
  const {Page, Runtime} = client;
  // Enable events on domains we are interested in.
  Promise.all([
    Page.enable()
  ]).then(() => {
    return Page.navigate({url: 'https://example.com'});
  });
  // Evaluate outerHTML after page has loaded.
  Page.loadEventFired(() => {
    Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
      console.log(result.result.value);
      client.close();
    });
  });
}).on('error', (err) => {
  console.error('Cannot connect to browser:', err);
});

该库实现的各个模块详细的文档:Chrome debugger protocol viewer

Chrome debugging protocol

chrome-remote-interface其实是Chrome debugging protocol的实现,它才是基石。我在另外一篇文章里有简单介绍它的使用。 Chrome之远程调试协议(Remote debugging protocol)

Chrome Developer Tools是用HTML,Javascript,CSS编写的chrome开发者工具,然而Remote debugging protocol就是它用来与浏览器页面(pages)交互和调试的协议通道。采用websocket来与页面建立通信通道,由发送给页面的commands和它所产生的events组成。chrome的开发者工具是这个协议主要的使用者,第三方开发者也可以调用这个协议来与页面交互调试。

总结

Chrome Headless模式的出现让PhantomJS的作者停止维护了他的项目,可以预见不久所有主流的浏览器也会提供Headless模式,从而现有的Headless Browser的项目都会慢慢停止维护。
各大浏览器提供Headless模式可以让程序运行的环境更贴近用户访问的真实环境,得出的数据也会更加准确可靠。

参考文章