网页自动化工具,主要是可以通过写代码的方式,自动打开网站,输入,自动与页面交互,得到输出。
我们通常用的按键精灵,抢票软件,基本都是标准的网页面自动化工具。
目前,主流的网页面自动化工具有:
- Selenium
- PhantomJS
- Chrome HeadLess
他们都可以完成网页面上面的各种交互,今天简单介绍一下其中两项技术。
历史介绍
2004 年,ThoughtWorks 内部开发使用的一个工具,于2005年制成初始的 Selenium-RC
发布,至今十五年,已经发展成为一套完整的前端页面测试生态解决方案。
2011年,浏览器大战进入高潮时间,赢家除了有 Google Chrome 之外,还有一个更大的赢家,就是 NodeJS
, 浏览器大战对NodeJs的成熟起了不少催化作用。
同年,基于NodeJs技术的 PhantomJS 诞生,不同与 Selenium ,由于内置了一个 WebKit, PhantomJS 最大的特点就是 runnable without a UI
,就是不用打开一个浏览器,就可以进行模拟操作了,这点 Selenium 是无法做到的。
2017 年, Chrome 发布的版本 59, 支持以 HeadLess 模式启动。 通过使用WebSocket连接, 让外部与它进行通信进行控制,所以严格的来说,Chrome HeadLess 仅是 Chrome 的一种启动方式,但它提供了一整套命令操作,官方也发布了基于Nodejs 的 Puppeteer 工具包,非常容易使用,也可以使用第三方或自己研发的包进行控制。
技术概览
总体上来说,技术差别如下:
对比项目 | Selenium | PhantomJS | Chrome HeadLess |
---|---|---|---|
依赖环境 | 需要安装浏览器和对应的driver | 仅NodeJs | 需要安装Chrome 或 Chrome-canary 或 Chromium,大部分框架基于Nodejs |
编程环境 | 支持多种编程语言,主流的都在其中 | JavaScript/TypeScript | 简单的需求命令行,其它的扩展,目前基本都是JavaScript/TypeScript |
主流框架 | 自带,少量三方 | 自带的 | 自带,三方相对较多 |
性能分析 | 无 | 有 | 有,功能同Chromen性能分析工具 |
浏览器 | 全部浏览器 | WebKit内核 | 自带Chorme |
相同点:
- 这三种技术,都可以直接或间接实现基础的网页面的各种页面操作,窗口管理,状态管理等基本功能,其中 PhantomJS 和 Chrome HeadLess 功能比较相似(Chrome HeadLess 设计之初参考对象就是前两者)
- 支持 Windows、 Linux、 macOS 操作系统,Linux 方面,由于发行版众多,三者貌似者仅在 Unbuntu 上做了测试,理论上其它发行版也没差。
不同点:
- PhantomJS 与 Chrome HeadLess ,最主要的不同是 PhantomJS 是内置的一个版本较低的 webkit 内核 ,而 Chrome HeadLess 的内核总是最新的,自家的 Blink 内核.
- Selenium 与后两者的不同一: 前者是基于机器上安装的浏览器,通过对应的 Driver 进行操作,后两都都是内置,不需要Driver中间层,所以前者可以支持几乎所有浏览器,后者只支持自己本身。
- Selenium 与后两者的不同二: 前者是更像是一整套生态解决方案,后两者仅像一个工具。前者支持各种主流开发语言,并且提供了 IDE 录屏回放工具,非常方便。后者则可通过第三工具库进行扩展。
- Selenium 与后两者的不同三: 后两者支持一些个性化的功能,比如保存PDF,浏览器功能开关等。
Selenium
Selenium 最大的特点就是系统非常完善,经过十多年的演化,Selenium已经构造出了自己的生态圈,由以下部分组成,可以根据不同情况选择使用。
- Selenium WebDriver : 包括了各种语言的库文件,远程控制器,
- Selenium IDE : 浏览器插件,支持 Chrome 与 FireFox
- Selenium Grid : 如果需要把任务放在一个集群上面,分布式运行,Selenium Grid是一个现成的解决方案。
不仅有强大的生态圈,Selenium 几乎支持所以浏览器(需要安装Driver),是其它技术无法比的,
- Chrome
- Firefox
- Safari
- Opera
- IE (仅IE11,且需要做一些额外配置)
- Edge
另外,Selenium 支持各种主流编程语言,包括
- Ruby
- Java
- Python
- C#
- JavaScript
所以,可以很轻松的将 Selenium 技术融入到目前正在使用的技术栈。
Selenium Grid: 如果需要把任务放在一个集群上面,分布式运行,Selenium Grid是一个现成的解决方案,
Chrome HeadLess
这里仅介绍后来者 Chrome HeadLess
, 先行者 PhantomJS
由于功能和 Chrome HeadLess
大部分时候,不再推荐PhantomJS。
使用 Chrome HeadLess 的两种方式
- 直接通过命令行,非常简单的业务,比如截图,打印等,直接运行命令就可
chrome \
--headless \ # 使用 headless 模式.
--disable-gpu \ # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \ # 远程调试端口,默认9222
https://www.xdnote.com # 打开链接. 默认是 about:blank.
常用命令:
--dump-dom 打出页面DOM结构
--print-to-pdf 导出PDF
--screenshot 屏幕截图
--window-size 设置网页大小
- 使用工具
目前搭配 Chrome Headless
的官方工具,是 Puppeteer ,一句话:Google 团队出品。
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
console.log(await browser.version()); // 打印 user agent
await page.goto('https://www.xdnote.com', {waitUntil: 'networkidle2'}); // 打开页面
await page.pdf({path: 'page.pdf', format: 'A4'}); // 页面打印成PDF
await browser.close(); // 关闭浏览器
})();
另外还有一个低层工具: chrome-remote-interface ,相对于Puppeteer, API更加底层,意味着更多的细节控制,也意味着实现起来需要更多的代码。
const CDP = require('chrome-remote-interface');
(async function() {
const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});
const {Page} = protocol;
await Page.enable();
Page.navigate({url: 'https://www.xdnote.com/'}); // 打开页面
// 等待 "window.onLoad"
Page.loadEventFired(async () => {
const manifest = await Page.getAppManifest(); // 获取app mainfest
if (manifest.url) {
console.log('Manifest: ' + manifest.url);
console.log(manifest.data);
} else {
console.log('Site has no app manifest');
}
protocol.close();
chrome.kill(); // 关闭浏览器
});
})();
需要说明的是, chrome-remote-interface 并不会默认启动Chrome,所以你可以手动用命令行启动,或者使用 chrome-launcher
启动,比如:
const chromeLauncher = require('chrome-launcher');
function launchChrome(headless=true) {
return chromeLauncher.launch({
// port: 9222, // 默认9222
chromeFlags: [
'--window-size=412,732',
'--disable-gpu',
headless ? '--headless' : ''
]
});
}
launchChrome().then(chrome => {
console.log(`Chrome debuggable on port: ${chrome.port}`);
});
参考阅读
- DevTools Protocol Viewer - API 文档
- chrome-remote-interface - chrome-remote-interface Nodejs 模块
- Lighthouse - 一个性能分析工具
- chrome-launcher -Chrome 启动器
- "The Headless Web" - DEMO
技术选型推荐
通常技术选型和需求相关,通常我们使用网页自动化框架,需求可能是以下几个之一:
- 编写测试用例:测试网页是否正常,录㓡行为等。
- 编写爬虫软件:传统的网络抓包爬虫无法拿到渲染后的页面
- 制作各类工具:流程处理、按键点击,外挂等等
粗暴推荐:
- Selenium 是一个万用的框架,基本可以作为首选,缺点是稍微比其他两个重一点,不是所有人都喜欢,总之,满足以下几点之一,选择 Selenium
- 需要运行测试用例:Selenium最初就是用来做测试用例的,能与各种编程语言的单元测试框架完美结合
- 需要跨浏览器测试:其他两个都无法支持全浏览器,Selenium甚至都可以支持IE。
- 项目本身重量级别:重量级别项目,Selenium提供了一整套生态,大部分的实际问题都会有解决方案。
- 不想使用NodeJs,想使用Python 或者 Java 等语言
- 不想用 Selenium 时,选择 Chrome HeadLess 即可, PhantomJS基本上没有绝对优势优于Chrome,总之,以下几点时,选择 Chrome Headless
- 小型工具等开发:项目本身比较小,电脑上只需要安装Chrome浏览器即可,简单的需求甚至可以通过命令行完成而不需要编程。
- 需要进行浏览器底层控制: Selenium 无法控制浏览器的一些底层行为,而Chome可以
- 网页性能分析:和开发者工具一样,提供性能分析模块自由实用
- 实在不想安装 Chrome ,选择 PhantomJS 即可。