初探 Headless Chrome
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相关推荐
- Web自动化之Headless Chrome概览
Web自动化 这里所说的Web自动化是所有跟页面相关的自动化,比如页面爬取,数据抓取,页面内容检测,页面功能测试,页面加载性能测试,页面回归测试等等,当前主要由如下几种解决方式: 文本数据获取 这就是 ...
- Serverless 实战——使用 Rendertron 搭建 Headless Chrome 渲染解决方案
为什么需要 Rendertron? 传统的 Web 页面,通常是服务端渲染的,而随着 SPA(Single-Page Application) 尤其是 React.Vue.Angular 为代表的前端 ...
- PuppeteerSharp: 更友好的 Headless Chrome C# API
前端就有了对 headless 浏览器的需求,最多的应用场景有两个 UI 自动化测试:摆脱手工浏览点击页面确认功能模式 爬虫:解决页面内容异步加载等问题 也就有了很多杰出的实现,前端经常使用的莫过于 ...
- .net core + headless chrome实现动态网页爬虫
一般的http请求库只能够抓取到网页的静态内容,如果想抓取通过js动态生成的内容可以使用没有gui的browser库,之前许多人会使用phantomjs作为headless browser,不过现在p ...
- Google Puppeteer加入到headless Chrome的工具行列
Chrome DevTools团队发布了Puppeteer,一个基于Node API的headless Chrome工具.Puppeteer提供了与其他第三方工具相似的功能,促使它们不断地创新与进步. ...
- Puppeteer -headless Chrome 的 Node.js API
Puppeteer 是一个控制 headless Chrome 的 Node.js API .它是一个 Node.js 库,通过 DevTools 协议提供了一个高级的 API 来控制 headles ...
- 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法
by Joyz 通过乔伊斯 在Docker中使用Python Selenium和Headless Chrome进行网站自动化测试的方法 (A recipe for website automated ...
- 用Python驱动Headless Chrome
Headless Browser(无头的浏览器)是什么鬼? 简而言之,Headless Browser是没有图形用户界面(GUI)的web浏览器,通常是通过编程或命令行界面来控制的. Headless ...
- 什么是 Headless Chrome
什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...
最新文章
- android获取元素路径,Appium元素定位(name、classname、相对路径、绝对路径\、list)...
- 动态的根据一个资源名获得到对应的资源id
- 公司--页面调用日期控件 WdatePicker日历控件使用方法
- python编程语言好学吗-转行零基础该如何学习python?很庆幸,三年前的我选对了...
- 【TensorFlow】ValueError: Shape must be rank 1 but is rank 0 for ' ’ with input shapes: [].问题
- Android给TextView和EditText等控件设置透明背景、圆角边框
- 蓝桥杯 ADV-112 算法提高 c++_ch02_01
- oracle里的关键字有哪些,oracle中的一些关键字
- cc2530按键流水灯c语言程序,CC2530流水灯程序
- kettle下载百度网盘地址含入门教程6(多表关联插入更新)
- php短信验证码的前台代码怎么写,php短信验证码接口代码示例
- Adaptive vision
- Nginx配置域名重定向/域名跳转
- Redis事务与Pipeline功能
- 多媒体教室计算机加投影机和电子白板配置方案
- sharePoint 发生意外错误.显示错误详细信息
- 分布式调度框架Elastic-Job
- 【智能优化算法】基于人工蜂群算法求解多目标优化问题附matlab代码
- 再谈用Excel计算年龄
- Ubuntu sources.list 换清华源