AutoPagerizeの設定復習

AutoPagerizeの設定をする方法を復習がてらにScientific Americanの記事に対して設定してみようと思う。

ちなみに、以前作ったAutopgerizeのSITEINFO。アイテム: My epub library : Bookworm ePub reader - データベース: AutoPagerize - wedataと、アイテム: book : Bookworm ePub reader - データベース: AutoPagerize - wedata。前者は変更が作った後に第三者によって加えられていた。はじめてコラボレーティブなことを体験したかもしれない。一応自分で作った物なので、かなり復習しやすいと思うので、参考にしながら作る。

まずWikiを読みはじめる、AutoPagerize Wiki: About SITEINFO (ja)

と同時に、前回はSITEINFOに書きこんで反映されるのに一日程度掛かるという事実を知らずに作りはじめて少しうーん、なかなか反映されないなぁと試行錯誤してしまった経験を生かして、ローカルでやる。というわけで、GreasemonkeyautopagerizeスクリプトEmacsで開いた。

var SITEINFO = [
/* sample
{
url: 'http://(.*).google.+/(search).+',
nextLink: 'id("navbar")//td[last()]/a',
pageElement: '//div[@id="res"]/div',
exampleUrl: 'http://www.google.com/search?q=nsIObserver',
},
*/
/* template
{
url: '',
nextLink: '',
pageElement: '',
exampleUrl: '',
},
*/

]

このようなものがあるので、そこに記述していく。

項目の上から考えていこう、url;はどういう内容になるだろうか。urlには対象のurl(文字列)にマッチングするを正規表現で作ってやればよい。Heat Exhaustion: Has the Adelie Penguin Met Its Match?: Scientific Americanこれが今開いている適当なScientific Americanの記事である。もうひとつLong Live the Web: A Call for Continued Open Standards and Neutrality: Scientific AmericanがScientific Americanの為にSITEINFOを書くかと思った理由であるティム・バーナーズ・リーの記事。

http://www.scientificamerican.com/article.cfm?id=has-the-adelie-peguin-met-its-match
http://www.scientificamerican.com/article.cfm?id=long-live-the-web

まぁ、適当に作ろうと思うので(よいこのみんなはまねしちゃ駄目だぞ)二つに共通するものであればおkなわけで。
http://www.scientificamerican.com/article.cfm?id=はどのページでも大体共通だと思われる。それ以降は任意の文字列らしい。

http://www.scientificamerican.com/article.cfm?id=has-the-adelie-peguin-met-its-match&page=2
ちなみにこれが2ページ目の文字列である。あまり問題なく正規表現でなんとか出来そうな気がする。

^http://bookworm\.oreilly\.com/(?:library|page)/
^http://bookworm\.oreilly\.com/view/
この2つが前回作成したものである。

それを参考に作ってみると、
^http://www\.scientificamerican\.com/article\.cfm\?id=
といった感じだろうか。?部分の前に\をつけてみたがどうだろう。必要だろうか。おそらく?は正規表現 - Wikipediaによると量化の符号であるらしいので必要だと思われる。で、urlの部分はこんな感じでいいのではないだろうか。とりあえず違ったらまた戻ってこればよい。進もう。

次にnextLink:である。これにはXpathを使う。ついでにpageElement:もXpathを使うので同時並行的にやっていこう。exampleUrl:もすぐに指定できるのでとりあえずAutopagerizeがそのSITEINFOで動く例となるURLであればよい。http://www.scientificamerican.com/article.cfm?id=long-live-the-webを指定しよう。

url: '^http://www\.scientificamerican\.com/article\.cfm\?id=',
exampleUrl: 'http://www.scientificamerican.com/article.cfm?id=long-live-the-web',
が確定した。url:の方は確かめていないので未確定だが。

では、Xpathを使用するnextLinkとpageElementの指定に入る。

nextLink //a[text()="next →"]
pageElement //table[@id="bw-library"]

nextLink //span[@class="bw-next"]/a
pageElement //div[@id="bw-book-content"]

という以前作ったXpathがある。結構難しかったんだこれが。正直Xpathをどうやって覚えたのかは忘れた。かなりのサイトを調べた記憶がある。正直Xpathにはそれなりの勉強を要した。そして勉強方法を忘れたw肝心なところを覚えていない最悪である。とりあえずぐぐりまくったのは確か。

//というのがあるが、基本Xpathというのは根構造?木構造?樹構造?XML Path Language - Wikipediaによると木構造。であって、//をつければなんか要素的なものに飛べるようになるってことらしいんで便利なので使うのですぞみたいな感じなことを思い出した。//ってのはおそらく省略構文ってやつかな。後、SITEINFOに載っているほかのAutopagerizeの設定を見ながらXpathについて学んだ記憶がある。実際そうしてほぼ実践的に試行錯誤しながら作った。

簡単な例を示す。

* //a[@href='help.php']

この例では、[@href='help.php'] の部分が述語である。 このXPath式は、href 属性をもち且つその属性値が 'help.php' である、全ての a 要素ノードを指定する。

まぁ、こんな感じなのである。

では、実践的に作っていこう。
ちなみに、この実践的に作っていくのとこういう感じでGreasemonkeyで色々するようなときとかサイトの何かを調べるときはFirebug使いまくる。おいらもSITEINFOを作るときにこれまたぐぐりまくってFirebugとそれなりに親しくなりました。これも大変でしたが。どう覚えたのかは記述していないという完全なる愚作。XpathFirebugが入る時点でなかなか難しかったんですよぼくにははい。というわけで今から俺用メモということにして自分だけわかればいいか。というかそうなってしまう。

<a href="article.cfm?id=has-the-adelie-peguin-met-its-match&amp;page=3" linkindex="152">Next&nbsp;></a>

的な部分が、Scientific Americanの記事におけるNextLinkらしい。
さらにそのコードの前後もみて見るが、対象に出来そうな部分はないようだ。というわけでNextのところを使う。
前回作った、下記を参考にする。

nextLink //a[text()="next →"]

//a[text()="Next >"]
だろうか。ちょっと不安である。$nbsp;の辺りがガチで。

だが次に進もう、pageElementを作る。
Scientific Americanの記事のページの場合、コメントを表示している部分があるのでそれより上となるだろう。

<div id="articleContent">

というガチヒットっぽいところがあったのでそれでやってみよう。
これも前回作った下記を参考にする。

PageElement //div[@id="bw-book-content"]

//div[@id="articleContent"]
となりそうである。

よし、一応これで全て必要なものはでそろったので、Greasemonkeyの方に記述してみる。
templeteを埋める

/* template
{
url: '',
nextLink: '',
pageElement: '',
exampleUrl: '',
},
*/

{
url: '^http://www\.scientificamerican\.com/article\.cfm\?id=',
nextLink: '//a[text()="Next >"]',
pageElement: '//div[@id="articleContent"]',
exampleUrl: 'http://www.scientificamerican.com/article.cfm?id=long-live-the-web',
},

となった。とりあえずこれでセーブして、ページのリロードを掛けてみる。どうだろうか。

ふむ、どうも駄目である。url:からして機能していないようだ。右上にAutopagerizeが動くページです的な■が出てないことからもわかる。

いや、でもどうなんだ、それだけじゃないっぽいぞと思いやはりurlをヒットしやすいものにして、nextLinkを疑う。これだと2ページ目までは表示される、そしてpageElement:も成功であることがわかった。で、何故かこの状態で全文表示されてしまう。なんぞwww

{
url: '^http://www\.scientificamerican\.com/article',
nextLink: '//a[text()="2"]',
pageElement: '//div[@id="articleContent"]',
exampleUrl: 'http://www.scientificamerican.com/article.cfm?id=long-live-the-web',
},

にっちもさっちもいかなくなったのでSITEINFOにてtext()で検索を掛けて実例を確認。こう変更したら動くようにはなった。

nextLink: '//a[contains(text(),"Next")]',

ただ、これだとNextっていう文言のリンクは全て拾ってしまうようだ。なので、divを前につけてpagenation的なidがついてたからそれで制御しようと思う。SITEINFOの他の例もそうしている。

<div id="articlePagination">

となっているので、これを使おう。Xpathでは上の階層なので前につければよい。

nextLink: '//div[@id="articlePagination"]/a[contains(text(),"Next")]',

最終的にこうなった。後はurl:の確認をしていく。

ふーむどうも駄目だなぁ。

{
url: '^http://www\.scientificamerican\.com/article\.cfm\?',
nextLink: '//div[@id="articlePagination"]/a[contains(text(),"Next")]',
pageElement: '//div[@id="articleContent"]',
exampleUrl: 'http://www.scientificamerican.com/article.cfm?id=long-live-the-web',
},

url:はここまでで諦めよう。延長していったんだが、?より先id以降がどうも駄目だ。まぁこれでもいいだろう。おかしなページを食って変な挙動をすることはおそらくないはず。
というわけで、最終的にこうなった。終わり。バーナーズリーの記事でも動いてるしおk。SITEINFOに登録しておく。done.
アイテム: Scientific American - Article - データベース: AutoPagerize - wedata

と思ったら、SITEINFOをぐぐってみたら、既にScientific Americanの項目があった、だがそれは動いていないようなので修正を掛けておくことにする。

なんか人のを修正するのは気が引けるがしょうがない。

アイテム: Scientific American - データベース: AutoPagerize - wedata

というわけで、これが自分の修正したものである。exampleUrIはエゴで変えた。とりあえず動くと思うが、SITEINFOがGreasemonkeyAutopagerizeに反映されるまではあんまり自信ないw
あぁ、Cacheの削除がGreasemonkey版は出来たんだと思って削除して試してみた。おk動いた。問題なし。