SITEINFOの書き方入門
SITEINFOは次のページへのリンクがどれかを示すnextLinkと、ページの中の本文部分を示すpageElementとでできています。
nextLinkは複数にマッチするXPathでも大丈夫です。複数の要素にマッチするときは、一番はじめにマッチしたものが使われます。よくページの上部と下部に同じナビゲーションが入っているページがありますが、そのときも片方だけの次のページへのリンクにマッチするようにXpathを書かなくてもAutoPagerizeがマッチしたものの中で一番はじめのものを使ってくれます。(実装はそうなってるけど仕様としてどうなのかは知らない)
AutoPagerizeのSITEINFOと同様な仕組みはLDRizeやLDR Full Feedでも用いられているので、書けるようになると他のところでも役に立ちますよ。他にもまじめにXSLTでバリバリ使われます。GRDDLとかも。 だからXPathがわかるようになるといいですよ。
じっさいにSITEINFOを作ってみましょう
The Whole World is peaceful. - snj14師曰く、「この世界はXPathにあふれておる。みてみよ、あの街を、あの風景を」を参考に、実際に作ってみましょう。
前準備
SITEINFOのXPathを作るにはFirebug :: Firefox Add-onsがないと大変です。まずはFirebugをインストールしておいてください。
pageElement部分を見つける
FirebugをインストールしたらAutopagerizeしたいページを開いて、Firefoxのステータスバーに表示されるFirebugのアイコンをクリックして開きます。

開いたらウインドウの下のほうにFirebugのコンソールが出てきます。Console,HTML,CSSなどとタブが並んでいるのからHTMLを選んでクリックするとページのHTMLの構造を見ることができます。
http://f.hatena.ne.jp/ku0522/20080420234655
表示されているHTMLタグの上にマウスを移動させると、そのタグに対応する部分がブラウザのウインドウの中で強調表示されて、どこにあるのかがわかるようになっています。
pageElementにあたる部分をinspect elementして探す。
HTMLツリー上で対応する部分が表示されるので、それを見ながらfirebugコンソールで$x()を使ってXPathを調整する。
おんなじことをnextLinkでもやる。
SITEINFOの書き方のこつ
次にデザイン、マークアップの観点から分類、それぞれのアプローチについて解説。
nextLink
"次のページ"へのリンクがあるもの

上の画像のはてなブックマークのページのように、今みているページのページ数に依存しないで、常に今みているページの"次のページ"へのリンクが決まった位置に存在するデザインのナビゲーションになっているときは、その次のページへのリンクを表すXPathを書くのが簡単です。
この場合、たいていは以下のどれかのケースに当てはまります。
rel="next"でマークアップされているケース
次のページへのリンクにrel="next"という属性がつけられていることがあります。このときは
//a[@rel="next"]と書けるので精度が高く、変化に強いXPathになります。
特定の属性(classやidなど)が指定されているケース
id("nextpageID")/aとか//a[@class="nextpageClass"]とか。
class指定は厳密に書くと//a[contains(concat(" ", normalize-space(@class), " "), " nextpageClass ")]
次のページのリンクに特定の文言、画像などが含まれるケース
a[contains(text(), "")] で書けるけど、気まぐれだしi18nの面でもよくないです。operaのアプローチ。»とかいれるのもいいです。
なにもついてないけど右端に置かれているもの
ある要素を指定して、その最後の子要素を取得するといいです。
a[last()]なかんじ。
数字だけのもの
Userscripts.orgの検索結果のように、ページ番号だけが表示されて次のページへのリンクが独立して存在しないようなデザインのナビゲーションもあります。
このときはちょっと厄介です。
いまのページの次の要素を指定するケース
ふつうはいまのページだけ、わかりやすいように強調されていたりするので、それを目印にして b/following-sibling::a というかんじで指定できます。
pageElement
tableで組まれていてclassやidがなくて書きにくいケース
何番目のtableかで指定したり、cellpaddingの微妙な値で指定すると、変化に弱いXPathになってしまいます。
pageElementになる部分にだけ含まれている画像がある場合、その画像を基準にしてXPathを書きます。その画像の一番近い祖先のtableという書き方をすると、変化に強いXPathになります。
例: ヤフーオークション検索結果のpageElement
//img[contains(@src,"down.gif") or contains(@src,"up.gif")]/ancestor::table[1]
pageElementが複数のpでできていたりするケース
CNETの記事のように、長文を複数のページに分割しているものに多いタイプです。HTMLの組まれかたによって難しくなります。 following-siblingを駆使すると表現できることもあります。
following-sibling::node()[ following::kokomade ]
- AutoPagerize pageElement ここよりもあとでここより前、みたいなのが書きたいとき - ロックスターになりたい
- ここよりも後でここより前を指定するXPath - 0x廃棄階層 - 統治局
id属性が重複しないようにする
AutoPagerizeがページを継ぎ足すことにより、本来ページにひとつだけであるべき同名のid属性を持つ要素が複数存在するようになると、ページ内スクリプトや他のGreaseMonkeyスクリプトが正常に機能しなくなることがあります。こういった場合、id属性が重複しないようにXPathの書き方を工夫する必要があります。
たとえばはてなダイアリーの場合、id属性が"days"であるdiv要素の中に、class属性が"day"であるdiv要素が個別記事として入っています。この場合、単に
id("days")
ではなく、
id("days")/div[contains(concat(" ", @class, " "), " day ")]
としたほうが不具合は起こりにくくなります。
other tools
bookmarklet
Perl
実行例
% scraper 'http://sample.example.com/path/to'
scraper> process 'id("pageElement")' , WARN