2019独角兽企业重金招聘Python工程师标准>>>

什么是 Headless Chrome

Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。相比于现代浏览器,Headless Chrome 更加方便测试 web 应用,获得网站的截图,做爬虫抓取信息等。相比于出道较早的 PhantomJS,SlimerJS 等,Headless Chrome 则更加贴近浏览器环境。

如何获取 Headless Chrome

目前,Mac 上 Chrome 59 beta 版本与 Linux 上的 Chrome 57+ 已经开始支持 headless 特性。Windows 上 Chrome 暂时不支持,可以使用 Chrome Canary 60 进行开发。

如何在终端中使用

在Mac上使用前,建议先绑定 Chrome 的别名

alias google-chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"

Linux下无需绑定别名,从官网上下载最新版 Chrome 之后直接运行以下命令即可。

然后,在终端中输入:

google-chrome --headless --disable-gpu --remote-debugging-port=9222  https://github.com

增加 --disable-gpu 主要是为了屏蔽现阶段可能触发的错误。

此时,Headless Chrome已经成功运行了。打开浏览器,输入 http://localhost:9222,你会看到如下的界面:

在终端中,我们还可以做以下操作:

获取屏幕截图:

google-chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://github.com

获取页面为PDF:

google-chrome --headless --disable-gpu --print-to-pdf https://github.com

打印页面DOM:

google-chrome --headless --disable-gpu --dump-dom https://github.com/

远程控制

在上文中讲述的都使用终端命令启动 Headless Chrome,下文以获取截图为例,尝试如何在程序里控制 Headless Chrome。

安装依赖

npm install lighthouse chrome-remote-interface --save

实现截图的大体思路为:通过使用 lighthouse 启动 Headless Chrome,然后通过 chrome-remote-interface 远程控制浏览器,使用 Page 监控页面的加载,使用 Emulation 模块调整视口缩放,最终生成一张截图。

const { ChromeLauncher } = require('lighthouse/lighthouse-cli/chrome-launcher')
const chrome = require('chrome-remote-interface')
const fs = require('fs')
const deviceMetrics = {width: 1200,height: 800,deviceScaleFactor: 0,mobile: false,fitWindow: false
}
const screenshotMetrics = {width: deviceMetrics.width,height: deviceMetrics.height
}
let protocol
let launcherfunction launchChrome () {const launcher = new ChromeLauncher({port: 9222,autoSelectChrome: true,additionalFlags: ['--window-size=412,732', '--disable-gpu', '--headless']})return launcher.run().then(() => launcher)
}
function getScreenShot () {const { Page, Emulation } = protocolreturn Page.enable().then(() => {Emulation.setDeviceMetricsOverride(deviceMetrics) // 配置浏览器尺寸Emulation.setVisibleSize(screenshotMetrics) // 配置截图尺寸Page.navigate({ url: 'https://github.com/' })return new Promise((resolve, reject) => {Page.loadEventFired(() => {resolve(Page.captureScreenshot({ format: 'jpeg', fromSurface: true }))})})}).then(image => {const buffer = new Buffer(image.data, 'base64')return new Promise((resolve, reject) => {fs.writeFile('output.jpeg', buffer, 'base64', err => {if (err) return reject(err)resolve()})})})
}
launchChrome().then(Launcher => {launcher = Launcherreturn new Promise((resolve, reject) =>{chrome(Protocol => {protocol = Protocolresolve()}).on('error', err => { reject(err) })})}).then(getScreenShot).then(() => {protocol.close()launcher.kill()}).catch(console.error)

这里使用 lighthouse 提供的 ChromeLauncher 模块来调用 Chrome,如果电脑上安装了Chrome Canary,lighthouse 默认会启动 Chrome Canary,可以将 autoSelectChrome 设置为false 然后自行选择使用什么版本。

通过 chrome-remote-interface 配合 Headless Chrome,我们还可以做更多事情。

使用 CSS 和 DOM 模块,可以获取和设置页面中的 DOM 节点内容和 CSS 样式。

function getStyle () {const { Page, CSS, DOM } = protocolreturn Promise.all([DOM.enable(),CSS.enable(),Page.enable()]).then(() => {Page.navigate({ url: 'https://github.com/' })return new Promise((resolve, _) => {Page.loadEventFired(() => { resolve(DOM.getDocument()) })})}).then(res => res.root.nodeId).then(nodeId => DOM.querySelector({ selector: '.btn-primary', nodeId })).then(({ nodeId }) => CSS.getComputedStyleForNode({ nodeId })).then(style => { console.log(style) })
}

使用 Runtime 模块,可以在页面运行时执行 JS 脚本。

function search () {const { Page, Runtime } = protocolreturn Promise.all([Page.enable()]).then(() => {Page.navigate({ url: 'https://www.baidu.com/' })return new Promise((resolve, _) => {Page.loadEventFired(() => { resolve() })})}).then(() => {const code = ['var input = document.querySelector(\'.s_ipt\')','var btn = document.querySelector(\'#su\')','input.value=\'123\''].join(';')return Runtime.evaluate({ expression: code })}).then(() => {return new Promise((resolve, _) => {setTimeout(() => {resolve(Page.captureScreenshot({ format: 'jpeg', fromSurface: true }))}, 3000)})}).then(image => {const buffer = new Buffer(image.data, 'base64')return new Promise((resolve, reject) => {fs.writeFile('output.jpeg', buffer, 'base64', err => {if (err) return reject(err)resolve()})})})
}

使用 Network 模块,可以读取并设置 UserAgent 和 Cookie 等信息。

function setUAandCookie () {const { Page, Network } = protocolreturn Promise.all([Network.enable(),Page.enable()]).then(() => {const userAgent = Network.setUserAgentOverride({ userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.71 Safari/537.36" })Network.setCookie({url: 'https://github.com',name: 'test',value: '123',domain: '.github.com',path: '/',httpOnly: true})Page.navigate({ url: 'https://github.com/' })return new Promise((resolve, _) => {Page.loadEventFired(() => { resolve() })})}).then(() => {return Network.getCookies()}).then(console.log)
}

在 Karma 中使用 Headless Chrome 进行单元测试

相比于 PhantomJS 等,使用 Headless Chrome 做单元测试更加贴近浏览器开发环境。同时 PhantomJS 作者也已经功成身退,在 Chrome 发布 Headless 模式后,发布通知不再维护 PhantomJS 项目。

安装依赖

npm install jasmine-core karma karma-chrome-launcher karma-jasmine -D

配置 Karma

// karma.conf.js
module.exports = function (config) {config.set({frameworks: ['jasmine'],files: ['./test.js'],browsers: ["Chrome_Beta_Headless"],customLaunchers: {Chrome_Beta_Headless: {base: 'Chrome',flags: ['--headless','--disable-gpu','--remote-debugging-port=9222']}},browserConsoleLogOptions: {level: 'log',terminal: true},reporters: ['progress'],autoWatch: false,singleRun: true})
}

编写测试用例

// test.js
describe('test', function() {it('should be true', function() {console.log(window.navigator.userAgent)expect(true).toEqual(true);});
});

配置npm script

// package.json
...
scripts: {test: "karma start"
}
...

在终端中运行

npm test

结果

从返回结果中可以看出,测试已运行在 Headless Chrome 环境下。

小结

本文简单介绍了一下 Headless Chrome 在终端的用法,以及如何使用 Headless Chrome 获取截图、获取页面中的CSS和DOM、设置UA和Cookie、运行JS脚本、配合 Karma 进行单元测试。接下来,就等着你探索更多关于 Headless Chrome 的用法了...

参考:

https://developers.google.com/web/updates/2017/04/headless-chrome
How to install and use Headless Chrome on OSX

转载于:https://my.oschina.net/wanjubang/blog/913457

初探 Headless Chrome相关推荐

  1. Web自动化之Headless Chrome概览

    Web自动化 这里所说的Web自动化是所有跟页面相关的自动化,比如页面爬取,数据抓取,页面内容检测,页面功能测试,页面加载性能测试,页面回归测试等等,当前主要由如下几种解决方式: 文本数据获取 这就是 ...

  2. Serverless 实战——使用 Rendertron 搭建 Headless Chrome 渲染解决方案

    为什么需要 Rendertron? 传统的 Web 页面,通常是服务端渲染的,而随着 SPA(Single-Page Application) 尤其是 React.Vue.Angular 为代表的前端 ...

  3. PuppeteerSharp: 更友好的 Headless Chrome C# API

    前端就有了对 headless 浏览器的需求,最多的应用场景有两个 UI 自动化测试:摆脱手工浏览点击页面确认功能模式 爬虫:解决页面内容异步加载等问题 也就有了很多杰出的实现,前端经常使用的莫过于  ...

  4. .net core + headless chrome实现动态网页爬虫

    一般的http请求库只能够抓取到网页的静态内容,如果想抓取通过js动态生成的内容可以使用没有gui的browser库,之前许多人会使用phantomjs作为headless browser,不过现在p ...

  5. Google Puppeteer加入到headless Chrome的工具行列

    Chrome DevTools团队发布了Puppeteer,一个基于Node API的headless Chrome工具.Puppeteer提供了与其他第三方工具相似的功能,促使它们不断地创新与进步. ...

  6. Puppeteer -headless Chrome 的 Node.js API

    Puppeteer 是一个控制 headless Chrome 的 Node.js API .它是一个 Node.js 库,通过 DevTools 协议提供了一个高级的 API 来控制 headles ...

  7. 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法

    by Joyz 通过乔伊斯 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法 (A recipe for website automated ...

  8. 用Python驱动Headless Chrome

    Headless Browser(无头的浏览器)是什么鬼? 简而言之,Headless Browser是没有图形用户界面(GUI)的web浏览器,通常是通过编程或命令行界面来控制的. Headless ...

  9. 什么是 Headless Chrome

    什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...

最新文章

  1. android获取元素路径,Appium元素定位(name、classname、相对路径、绝对路径\、list)...
  2. 动态的根据一个资源名获得到对应的资源id
  3. 公司--页面调用日期控件 WdatePicker日历控件使用方法
  4. python编程语言好学吗-转行零基础该如何学习python?很庆幸,三年前的我选对了...
  5. 【TensorFlow】ValueError: Shape must be rank 1 but is rank 0 for ' ’ with input shapes: [].问题
  6. Android给TextView和EditText等控件设置透明背景、圆角边框
  7. 蓝桥杯 ADV-112 算法提高 c++_ch02_01
  8. oracle里的关键字有哪些,oracle中的一些关键字
  9. cc2530按键流水灯c语言程序,CC2530流水灯程序
  10. kettle下载百度网盘地址含入门教程6(多表关联插入更新)
  11. php短信验证码的前台代码怎么写,php短信验证码接口代码示例
  12. Adaptive vision
  13. Nginx配置域名重定向/域名跳转
  14. Redis事务与Pipeline功能
  15. 多媒体教室计算机加投影机和电子白板配置方案
  16. sharePoint 发生意外错误.显示错误详细信息
  17. 分布式调度框架Elastic-Job
  18. 【智能优化算法】基于人工蜂群算法求解多目标优化问题附matlab代码
  19. 再谈用Excel计算年龄
  20. Ubuntu sources.list 换清华源

热门文章

  1. ThinkPad E440 加内存后导致开不了机
  2. Enterprise Library 4.1 Application Settings 快速使用图文笔记
  3. Chrome 的又一个bug?
  4. SQL Server 2005:你应该知道的13件事情
  5. Sentinel 发布里程碑版本,添加集群流控功能
  6. 016 在大数据中,SSH无密钥登录
  7. php处理json请求(php获取post请求的json数据的实现方法)
  8. Apache 配置的性能调优
  9. flex 3 使用手册
  10. 确保独立计算机上的EFS加密数据恢复