w3m-autopagerizeを公開予定

FirefoxAutoPagerizeid:swdyhさん作)がうらやましくなったのでw3m版も作ってみた。
というか、AutoPagerizeが生まれる前から「次のページ」ボタンが欲しくなってワンタッチでLocal CGIを起動して次のページリンクを見つけて押すようなものを作っていたのだ。だけど対応すべきサイトが膨大すぎるため自分が見るサイトしか対応していなくて公開してなかった。正直万人に使える代物ではなかった。
だが、AutoPagerizeの登場と最新版AutoPagerizeの設定データ(SITEINFO)がwebで公開されていることで状況が変わった。そこのデータを流用してしまえば、定番サイトは対応できるだろうと考えた。
しかし、壁はまだ残っていた。HTMLを解析してXPathで抜き出すまともなRubyのライブラリが存在しなかった。HpricotはいちおうXPathにも対応しているものの、いい加減であるため使いものにならないのだった。だが、この問題もついに解決した。真打HTMLパーサのNokogiriが登場したからだ。多謝。念願叶ってやっとXPathフルサポートのHTMLパーサが手に入ったのだ。libxmlを使っているから、大丈夫っしょ。しかも速い。

まず、http://wedata.net/databases/AutoPagerize/items.json からAutoPagerizeの設定データを拾い、Rubyスクリプトに変換する。これを使う。jsonなのでYAMLライブラリで解析できる。
次にdRubyサーバを立ててその設定スクリプトを読み込み、URLを受け付けて「次のURL」を応答する。dRuby化しておかないと設定スクリプトの読み込み等の初期化処理で1秒ほど遅れてしまう。短気な俺には耐えられない。だからこそdRuby化だ。
クライアントはw3mのLocal CGIだ。サーバに次のURLを尋ね、locationで飛ばすだけ。

AutoPagerizeと名乗っているけど、今のところ「次のページ」のURLに飛ぶだけの機能だ。本家みたいにスクロールによって自動的に読み込むようなことはw3mだからできない。ヘッダの削除も厳密には「Local CGIの結果を指定されたURLのものとする」機能がないとムリ。まあCGIプロキシだと限定的にできるかもしれないが…
それでも「次のページ」のリンクを探して押すよりもボタン一発で次のページに移れるのだから操作性は上がるだろう。

欲しい人いますか〜?
いるならそのうちgithubにでも置いておこう。おそらくこれがgithubデビューとなるだろう。

追記

ヘッダの削除は実装した。ただ、URLがLocal CGIのままなので元々のページへのリンクは作っておこう。わお、こりゃええわ。余計な部分が削られただけで見やすくなってる。SITEINFOを与えている人、メンテナンスしている人が神に思えてきた。
だけどただハックしただけなのでソースが汚すぎる。見るに耐えん。リファクタリングしとかな。

fast forwardはどうやらヒューリスティックに基いたやりかたのようだな。「次の」とか「次ページ」とかのリンクか。fallbackとして実装してみるかな。どういうパターンにしているかを調べた上でNokogiriに切り出させるか。AutoPagerizeのデータに基くやりかたが優れているのはヘッダなど余計な部分をpageElementで切り取っているところ。そうでないとシームレスにページをつなげることなんてできないからね。

w3m-autopagerizeは「次のURLを得る」機能と「ページの加工」機能に分けられるよな。今できる加工はpageElementによる切り出しのみだが、ユーザ設定で任意の加工ができるようにしておくとよさげ。JavaScriptを加工するとか、うざいテーブルレイアウトを叩き斬るとか。そうなるとw3m用のコンテンツフィルターとしても使えそうだ。となると、フィルター専用のLocal CGIも用意しとくべきだな。

追記

・ ttamo ttamo w3m シクシク……→「本家みたいにスクロールによって自動的に読み込むようなことはw3mだからできない」 2008/12/31

まあそんな悲しむことでもないと思う。スペースキーの代わりに「次のページ」ボタンを押せばいいだけなのだから。俺自身は変換キーを「次のページ」ボタンにしている。親指で押せるから操作感覚はスペース押してるのとかわらん。

追記

libxml2の地雷を踏んでしまった。DOCTYPE宣言のないHTMLではid関数にマッチしなくなる。DOCTYPE宣言がだぶっていてもlibxml2的にはokなのでNokogiriに解析させるHTMLに

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

をprependしておいた。バッドノウハウだな。

nokogiri.xpath(%{id("productReviews")}).first

via http://labs.gmo.jp/blog/ku/2008/07/libxmlhtmlxpathid.html

そこのブクマコメを見てみると、

・ kits kits xml, html, xpath XPath仕様としては、id関数を使うには、文書がID型属性を宣言したDTDを持つことが必要 2008/07/14

ぬぬ、そういうことか。はてなブックマークにはコメントがつけられるから新たな情報が入ることもある。