Chrome59(2017/05/27現在はベータ)から--headlessオプションを使うことでChromeをヘッドレスブラウザとして使えます。これをNodeJSから操作するにはchrome-remote-interface
というNPMパッケージを使うのですが、そのままですとなかなか面倒です。そこで、NightmareJS風にヘッドレスChromeを操作することができるライブラリをご紹介します。
GitHub: https://github.com/OnetapInc/chromy
基本的な使い方
このようにNightmareJS風のメソッドチェーンで操作することができます。visibleオプションを指定すればヘッドレスモードではなく通常モードでChromeを起動することもできます。
Chrome本体は標準的なインストールをしていれば自動的に最も新しいChromeを探してそれを起動します。
試す場合はChrome 59以上(2017/05/27現在はBeta)をインストールしてください。
const Chromy = require('chromy')
// not headless
// let chromy = new Chromy({visible:true})
let chromy = new Chromy()
chromy.chain()
.goto('http://example.com/')
.evaluate(() => {
return document.querySelectorAll('*').length
})
.result((r) => console.log(r)) // result()は一つ前の処理の結果を受け取る
.end()
.then(() => chromy.close())
Chromyはメソッドチェーンではなくasync/awaitを使ったインタフェースも用意されています。
const Chromy = require('chromy')
async function main () {
let chromy = new Chromy()
await chromy.goto('http://example.com/')
const result = await chromy.evaluate(() => {
return document.querySelectorAll('*').length
})
console.log(result)
await chromy.close()
}
main()
README.md に使えるAPIの一覧が載っています。NightmareJSと比べると足りないAPIもありますが、下記のような基本的なAPIはだいたい揃っています。
・ナビゲーション
・キーボード関連イベント
・マウス関連イベント
・フォーム関連のユーティリティ
・ブラウザ内でのJS実行やブラウザ内からのChromyへのメッセージ送信
・クッキー
・モバイルエミュレーション
Chromyのメソッドチェーンの実装(async-chain-proxy)
Chromyのメソッドチェーンは async-chain-proxy という別のライブラリを使って実装されています。
Chromy自体にはasync functionが定義されているだけです。
GitHub: https://github.com/OnetapInc/async-chain-proxy
このライブラリはオブジェクトを与えるとそのオブジェクトのメソッドをメソッドチェーンで呼び出すことができるプロキシオブジェクトを作ってくれるライブラリです。下記のコードを見れば何をしてくれるか一目瞭然かと思います。
class A {
async foo () {
console.log('foo')
}
async bar () {
console.log('bar')
}
}
const chainProxy = require('async-chain-proxy')
const obj = chainProxy(new A())
obj.foo().bar().end()
ChromyのNightmareJSとの違い
NightmareJSはElectronをベースにしていますので、レンダリングエンジンはChromyと同じくChromeが採用しているBlinkになります。現時点ではElectronはChromeのヘッドレスモードに対応していないため、起動にはxvfbなどでスクリーンを用意する必要がありますが、Chromyではその制約がありません。
そのほか、NighmareJSにはない機能として、モバイルのエミュレーション機能があります。
エミュレーションを使うとスクリーン解像度やユーザーエージェントなどの切り替えやタッチイベントのエミュレーションなどが簡単にできます。
const Chromy = require('chromy')
let chromy = new Chromy()
chromy.chain()
.emulate('iPhone6')
.goto('http://example.com/')
.evaluate(() => {
return navigator.userAgent
})
.result(console.log)
.tap(100, 200)
.doubleTap(200, 300)
.end()
.then(() => chromy.close())
NightmareJSの動向
NightmareJS自体がそのうちヘッドレスChromeで動かせるようになるんじゃないのか思っている方が多いと思いますが、たぶんなります。
関連Issue:
https://github.com/segmentio/nightmare/issues/1092
現在(2017/05/27)はElectronの対応待ちのようで、ElectronのIssueがこちら。
https://github.com/electron/electron/issues/228
動いてませんが、まぁそのうち対応するでしょう。たぶん。
まとめ的な
そのうちNightmareJSも対応するでしょうが、いますぐにでもそれっぽいAPIでヘッドレスChromeしたい方はぜひChromyを試してみてはいかがでしょうか。