RSSを生成していないページからRSSを生成するなんでもRSS 0.1bは、公開されているJSAI2005: なんでもRSS - HTML文書からのRSS自動生成によると、日付情報を目印にしてそのHTMLドキュメントの構造を推測して、各エントリ(item要素)のタイトルと本文を単語の統計的に処理して決定し、フィードを生成していると書かれています。
ウェブ上にあるHTMLドキュメントは Ask.jp : "xml" Search results. のように、RSSのitem要素に相当する部分に日付が含まれていないものもあります。
その中でも、大量のデータを複数のページにわけて表示しているHTMLドキュメントを対象に、ドキュメント中に含まれる繰り返し部分のXPathを生成するブログラムをjavascriptで作りました。
出てきた差分から、最も差分を多く持っている要素を繰り返し部分の親要素候補としてリストアップします。親要素候補に含まれる子要素に設定されているクラス名と、要素に含まれる文字列の長さをもとにして、ページに含まれる最も重要だと思われる繰り返し部分のXPathを生成します。

Arrayオブジェクトのshiftメソッドが上書きされているのが原因でスクリプトがエラーを出して止まります。XMLHttpRequestでページを取得できないため機能しませんlinkディレクトリに入れて、次のページへのリンクを選択してiterationDetectorを実行してください。


ちなみにコンソールに出てきたDOMのエレメントを表している部分にマウスを持っていくと、その部分の色が変わるので期待通りにXPathが生成されているかどうか目で見て分かります。





まずわかりやすいところでmozillaZineと違うのは、ページの右側にswickiと書かれたタグクラウドの部分があるところです。このタグクラウドにはタグの数だけ繰り返し構造が含まれていて、さらになぜかランダムに表示されているため、ページ間で差分をとると異なる部分として判断されます。
当初繰り返している回数が多い部分を、ページを構成している繰り返し部分と判定していたため、このswicki部分が抽出されていました。
ここでひとつ気がついたのが、人間にとって意味のある部分はページの中で(ふつうは)最も大きなピクセル数を持っているということでした。HTMLは人がブラウザでそこに書かれている情報を読みやすいように書かれているはずなので、多くのピクセル数が割り当てられている部分がページを構成している主要な繰り返し部分だと考えられます。そして要素のピクセル数は要素に含まれているテキストの長さに比例して大きくなるので、要素に含まれている文字数に応じて重み付けをしたところ、期待する動作をするようになりました。

一見うまく抽出できているように見えますが、HTMLを見てみるとひとつのエントリがh2タグとdivタグとで構成されていることが分かります。

h2とdiv)、XPathではひとつひとつの繰り返し部分を表現できません。
ひとつの繰り返しという単位を複数の要素で記述しているtechCrunchのHTMLがよくない、と主張することもできそうですが、よく考えると
Lists in HTML documents (ja)を見て分かる通り、dlタグはdtとddをひとつの繰り返しの単位として記述することができるようになっています。
dtとddを繰り返しの単位として表示しています。Nutch Mediawiki Search: createdocument - MDCは、1ページに8件の検索結果を表示します。その構造はdlタグの中にdtとddで各項目をリストしていくようになっています。


HTMLの仕様に、ひとつの繰り返しという単位を複数のタグで表すことが含まれている以上、何らかの方法でひとつの繰り返しがどこからどこまでなのかを推測し、それを表現する方法を考える必要がありそうです。
XMLHttpRequestで読み込んだあと、DOMDocumentオブジェクトにするときHTMLDocumentを(かなり無理矢理)生成する方法がわかったのでGM_xmlhttpRequestでwell-formedじゃないHTMLのコードを取ってきて新しく生成したHTMLDocumentでパースしてみるよに記述された方法を使っています。
しかしこの方法で生成されるDOMツリーはwell-formedへの変換方法がブラウザのウインドウ内でHTMLを表示するときは違うようです。
well-formed - Google 検索を見ると、昔formの前後に空白ができてしまうのを避けるために使われていたtrとtdの間にformを入れる方法が使われています。
<table class=tb style=clear:left width=100%><tr><form name=gs method=GET action=/search><td
これがウインドウで開くときと上記の方法を使うときとで違う部分として出力されました。
....もうひとつあった気がしたのですが思い出せないので思い出せたら追記します。
XPathで繰り返し部分を表現するため表現可能なページ構造が限られているため、Mozilla Developer Centerの検索結果ページ等は表現できません。しかし表現できないページの割合は高くないでしょう。
しかし、まだjavascriptで重い計算処理をやるのはつらく、またスクリプトで自動的に実行することができず毎回手作業でリンクを選択する、ページを切り替える、ことが必要で、さらにレンダリングされるサイズはだいたい文字数に比例するので文字数で代替可能というのがわかりました。perl等で実装していれば、自動化して多数のページを対象に調整を行って精度を高めやすかったかなと思います。
トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。
http://labs.gmo.jp/mt/mt-tb.cgi/177
comments