ウェブサービスである某チャットソフトで、管理者じゃないけどある内容を自動的に投稿したいということがあり、CasperJSを使ってみた。

そもそもはPhantomJSを使おうとしていたんだけど、その上に作られたCasperJSというものがあるというのを見て、そのほうが便利なんだろうとそちらを使ってみた(PhantomJSをちゃんと使っていないので、違いは分かってない)。

インストール

npmでも入れられるみたいだけど、Macではbrewでインストールできる:

$ brew install phantomjs casperjs

実行

JavaScriptで書いたコードを実行:

$ casperjs script.js

最新のNodejs、というわけではないらしく、アロー関数とかは使えなかった。

初期化

以下JSのコード。requireしたcaspercreateしてやる:

var casper = require('casper').create({
  viewportSize: {
    width: 1280,
    height: 768,
  },
})

viewportSizeの指定は必須じゃないけど、スクリーンショットを撮るときなどに。

メソッドはFluent Interfaceになっている。

XPathを使う

要素を指定する時に、XPathを使うことができる(Selectors):

var x = require('casper').selectXPath

ユーザエージェントの指定

casper.userAgent('CustomUA')

読み込みURL指定

startメソッドを使う:

casper.start('http://www.example.com/', function() {
  ...
})
  • 第2引数の関数内にそのページが開かれたらやりたいことを書く。
  • function内部でのthiscasper自身。

成功したら次の処理を行う

thenでつなぐ:

casper.start(...)
  .then(function() {
    ...
  })

DOM要素を探す

    this.waitForSelector('form[name="login"]')

読み込みが遅延したときなど、自動的に待ってくれる。

フォームに入力、Submit

fillメソッドを使う:

    this.fill('form[name="login"]', {
      email: 'foo@example.com',
      password: 'blahblahblah',
    }, true)
  • 第3引数でSubmit

時間待ち

waitでミリ秒待つ:

    this.wait(1000)

要素をクリック

click

    this.click(x('//*[text()="FooBar"]'))
  • リンクやボタンだけじゃなく、XPathで「これこれのテキストの要素」に対してクリック、ということもできる

ページ側でJavaScriptを実行する

DOM操作をしたい場合などにevaluateで呼び出せる。

    this.evaluate(function(message) {
      document.getElementById('textarea').value = message
    }, {
      message: MESSAGE,
    })
  • テキストエリアに文章を設定したかったけどAPIでのやり方がわからなかったので、evaluateを使った
  • 実行するコンテキストが違うので、変数は明示的に渡す必要がある
  • 簡単な結果なら返せる、とのこと(DOMとかじゃなく文字列とかならということだと思う、未確認)

スクリーンショットを撮る

capture

    this.capture('ss.png')

処理開始

runで実際に動作開始:

  .run(function() {
    this.echo('Done!').exit()
  })
  • 関数を与えた場合には、exitしてやる必要がある。