xpcshellでHTMLを取得してjQueryを使う

に挑戦してみた。

xpcshellでHTMLパース - hogehogeの続きともいえるが、HTMLパースの方法を変えている。前回はnsIXSLTProcessorから作ったが、今回はHTMLDocument の動的な作成: Days on the Moonを使用してHTMLDocumentを作成している。

実行すると、ajax.jsがこのURLのHTMLを取得して擬似windowを生成しその中にjquery-1.3.2.jsと第二引数のファイルを読み込む。という仕組み。

上記2つのファイルを同ディレクトリに置いて、さらにjquery-1.3.2.jsを置く。そして、jquery-1.3.2.jsを少し編集して、先頭部分にあるwindow = thisコメントアウトしておく。

例1

user.js

var res = [];
$("h3.answer-title .answer-time").each(function(i, elm){
  res.push($(elm).text());
});
print(res.join("\n"));

というファイルをつくり、

xpcshell ajax.js user.js http://q.hatena.ne.jp/1259814347

と実行すると、xpcshellが引数にuser.jsとURLを設定してajax.jsを実行してくれる。
結果は以下の通り。

[loading 'xpcshell.js'...]
==========================================
URL: http://q.hatena.ne.jp/1259814347
2009-12-03 13:53:52
2009-12-03 14:12:39
2009-12-03 15:50:02
2009-12-03 16:05:26
2009-12-03 13:53:52
2009-12-03 14:12:39
2009-12-03 15:50:02
2009-12-03 16:05:26

例2

ローカルファイルへ書き込みも行える

user.js

var res = [];
$("h3.answer-title .answer-time").each(function(i, elm){
  res.push($(elm).text());
});
var str = res.join("\n");
dump(BString(str, "Shift_JIS") + "\n");

var file = io.File("./log.txt");
io.writeFile(file, util.fromUTF8Octets(str) + "\n")

例3

ローカルファイルへ書き込んで、さらにFirefoxで開く

xpcshell ajax.js user.js http://b.hatena.ne.jp/teramako/

user.js

let html = <html>
  <head>
    <meta http-quiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>{document.title}</title>
  </head>
  <body>
    <h1>{document.title}</h1>
    <ul>
    </ul>;
  </body>
</html>;
$("h3.entry").each(function(i, elm){
  let a = $(elm).children("a:first");
  let [title, url] = [a.text(), a.attr("href")];
  html.body.ul.* += <li><a href={url}>{title}</a></li>;
});

let file = io.File("test.html");
let res = io.writeFile(file, html.toXMLString(), ">", 0644, "UTF-8");
if (res){
  let firefox = io.File("/usr/bin/firefox");
  let p = new Process(firefox);
  let args = [file.path];
  p.run(false, args, args.length);
}

制限事項

  • 非同期処理的なことは行えない
    • jQueryajax含め、XMLHttpRequestのasyncは行えない
    • setTimeout, setIntervalがない(擬似的に行えるようにしようと試みたが出来なかった)
  • 不完全なドキュメント
    • anchor(a)要素のhref属性は通常であれば、a.hrefで絶対URLとして取得できるが、そのままになる。
    • image(img)要素のsrcも同様

xpcshell使用時の注意事項

  • jsファイル内にvar str = "あいうえお"とした場合、Unicodeとして扱われていないため、Shift_JIS環境ならstr.lengthは10、UTF-8環境なら15となってしまう。
    • Unicodeに変換するにはUStringを使用する。
  • Windowsコマンドプロンプト上の場合にマルチバイトを出力する時は、Shift_JISに変換して出力する必要がある。
    • さらにUTF-8以外だとprint関数で出力出来ないのでdumpを使用する
    • 変換にはBString関数を使用すると良い。これはUnicodeを第二引数(省略時は"UTF-8")に変換する関数
    • dump(BString(str, "Shift_JIS") + "\n") な感じ。
  • BString,UString関数はxpcshell.jsに含まれる関数でデフォルトでは存在しない。
  • xpcshell.jsはxpcshell実行時にカレントディレクトリにあると自動的に読み込まれる(今回はその機能を使ってライブラリ的なオブジェクトや関数を読み込ませている)
  • Windows環境でxpcshell.jsがカレントディレクトリにある状態かつxpcshell.exeにPATHを通している時、xpcshel ...とするとjsファイルを実行しようとしてしまう。xpcshell.exe ...とすればOK

xpcshellの入手

Mozilla系アプリを自分ビルドすると作られるらしいが、もっと簡単な方法を

Ubuntu 9.10の場合

xulrunnerをインストールする。現時点だと、xulrunner-1.9.1.5。
僕の環境だと、ライブラリへのリンクが不完全だったので

cd /usr/lib
sudo ln -s xulrunner-1.9.1.5/libxpcom.so
sudo ln -s xulrunner-1.9.1.5/libxul.so
sudo ln -s xulrunner-1.9.1.5/libmozjs.so
cd /usr/local/bin
sudo ln -s /usr/lib/xulrunner-1.9.1.5/xpcshell

をした。

Windowsの場合

から、xulrunnerを入手。(1.9.1以上が良いかな)
そして、適当なところに展開。僕の場合はさらにPATHを通している。