xpcshellでHTMLを取得してjQueryを使う
に挑戦してみた。
xpcshellでHTMLパース - hogehogeの続きともいえるが、HTMLパースの方法を変えている。前回はnsIXSLTProcessorから作ったが、今回はHTMLDocument の動的な作成: Days on the Moonを使用してHTMLDocumentを作成している。
- xpcshell/xpcshell.js at master from teramako's scripts - GitHub
- ライブラリ。このファイル(xpcshell.js)があるディレクトリでxpcshellを実行すると自動的に読み込まれる。
- xpcshell/ajax.js at master from teramako's scripts - GitHub
- 第一引数にパースしたHTMLドキュメント内で実行するスクリプトを指定
- 第二引数以降に取得するURL
実行すると、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); }
制限事項
- 非同期処理的なことは行えない
- jQueryのajax含め、XMLHttpRequestのasyncは行えない
- setTimeout, setIntervalがない(擬似的に行えるようにしようと試みたが出来なかった)
- 不完全なドキュメント
- anchor(a)要素のhref属性は通常であれば、
a.href
で絶対URLとして取得できるが、そのままになる。 - image(img)要素のsrcも同様
- anchor(a)要素のhref属性は通常であれば、
xpcshell使用時の注意事項
- jsファイル内に
var str = "あいうえお"
とした場合、Unicodeとして扱われていないため、Shift_JIS環境ならstr.length
は10、UTF-8環境なら15となってしまう。- Unicodeに変換するにはUStringを使用する。
- Windowsコマンドプロンプト上の場合にマルチバイトを出力する時は、Shift_JISに変換して出力する必要がある。
- 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を通している。