SITEINFOのnextLinkケーススタディ
AutoPagerizeのSITEINFOを書くとき、ネックになりがちなのはnextLinkのXPath。
pageElementのXPathは割とシンプルに書ける*1し、insertBeforeは省略しても構わない。
というわけで、nextLinkのXPathのパターンを簡単にまとめてみる。
aタグを直接指定できるケース
次のページのURLを情報*2を含む要素を直接指定できるケース。精度が高く、メンテナンス面も優れる。
例:はてなダイアリー
AutoPagerize本体にも組み込まれている通り、aタグもしくは、linkタグのrel属性にnextが指定された要素を取得する。
-
- html
<link rel="prev" href="/os0x/?of=5" title="前の5日分">
nextLink: '//link[@rel="prev"]'
大抵nextとprevの両方があるが、そのどちらを使うかはサイトによってまちまち。
標準的で、間違いもないので、最も扱いやすいケース。
- 次のページを指す要素に特定の属性(classやidなど)が指定されている
例:FFFFOUND! http://ffffound.com/
-
- html
<a id="paging-next" rel="next" href="?offset=25&">next(<span class="shortcut">l</span>) »</a>
nextLink: 'id("paging-next")'
他には
'//a[@class="Next"]' //Flickr
や、
'//a[@accesskey="e"]' //(del.icio.us)
など。
- 次のページのリンクに特定の文言、画像などが含まれる
nextなどの文言が含まれるAタグを指定する。text()を調べるのはパフォーマンスに難があるので、特定要素以下に限定するように工夫することが望ましい。
例:Engadget Japanese http://japanese.engadget.com/
-
- html
<a href="/page/2/">次のページ</a>
nextLink: '//a[starts-with(text(),"次の")]'
他には、
'id("navbar")//a[child::img[@src="nav_next.gif"]]' //(Google Blog Search)
など。人間にとってわかりやすい反面、サイトのちょっとした変更で動かなくなることがある。
aタグの何番目に位置するか指定するケース
次のページへのリンクを直接は指定できないが、その親にあたる要素を指定し、その最初か、最後などの特定位置にある要素を取得するパターン。
精度の面はやや心もとないが、汎用性は高くよく使われている。
- ある要素を指定して、その最初の子要素を取得
例:Google
-
- html
<td class="b" nowrap=""> <a href="/search?q=AutoPagerize&hl=ja&rlz=1B3GGGL_jaJP245JP246&pwst=1&start=10&sa=N"><div id="nn"/><b>次へ</b></a> </td>
nextLink: 'id("navbar")//td[last()]/a'
ちなみ、上記の場合、
nextLink: 'id("nn")/..'
でも良い。
- ある要素を指定して、その最後の子要素を取得
-
- html
<div class="pager"> <p> 1 <a>2</a> <a>3</a> ... <a>10</a> <a href="./?of=20">次の20件></a> </div>
nextLink: '//div[@class="pager"][last()]//a[last()]'
兄弟要素から取得するケース
ページナンバーが1 2 3 ...と並んでいるだけの場合、次のページを特定することが難しい。
その場合、現在のページだけaタグ以外でマークアップされていることが多いので、そのタグを起点にその兄弟を取得することで次のページのURLを取得できる。
例:Softpedia http://www.softpedia.com/progSearch?src=firefox (oAutoPagerizeのみ)
-
- html
<b>1</b> <a>2</a> <a>3</a> <a>4</a>
nextLink: '//a[starts-with(@href,"/progSearch/")]/../b/following::a'
やや複雑だけど、Googleのようなページナビゲーションを使っているサイトでは汎用的に有効なので、困ったときはこの方法を試してみると良いかも。
[追記]
The art of AutoPagerize nextLink XPath writing « kuでさらなるアイディアを頂きました。
ちなみに上記の例は、following-siblingを使ったほうが良いですね。following-siblingは兄弟ノードのみ、followingでは兄弟ノードの子孫ノードも含まれます。
nextLink: '//a[starts-with(@href,"/progSearch/")]/../b/following-sibling::a'
[/追記]
とりあえず、こんなところで。
ここまで書いてみて思ったのだが、XPathをパターン分けするのではなく、ページナビゲーションをパターン分けして、それに対するXPathを見たほうがわかりやすかったかもしれない。
デザインの視点も入れれば非常に面白く、わかりやすい記事になりそうなので誰かが書いてくれないかな。