XPathをてきとうに作ってくれる機能を追加したwebscraperp.js

perlのWeb::Scraperみたいな記述で、ページの中からデータを取り出すwebscraper.jsという小さなjavascriptのライブラリに、要素をてきとうに渡したらてきとうにXPathを作って動いてくれるwebscraperp.jsというのを書きました。なんで最後にpをつけたかは思い出せません...

ブックマークレット

Web::Scraperのjavascriptバージョンwebscraper.jsと同じように、データを取り出したいページでブックマークレットでwebscraperp.jsを読み込んでFirebugコンソールで使います。
ブックマークレット(Firefox3専用)
webscraperp
コード
webscraperp.js

つかいかた

Web::ScraperのSYNOPSISで例としてあげられているebayだとアクセスしたときによって出品されているものが違っていてサンプルとしてわかりにくそうなので、今回はebayほどには変化しないスターバックスさんの店舗検索結果(住所・店名・条件から探す)を例に使わせてもらいます。


はじめに店舗検索結果(住所・店名・条件から探す)を開いてブックマークレットでwebscraperp.jsをロードします。

つぎにFirebugのコマンドラインでWebScraperPのインスタンスを作ってaddFieldContainsTextで取り出したい項目が含んでいるテキストを指定していきます。


try {
var p = new WebScraperP(document);
p.addFieldContainsText( "銀座松屋通り店", "name" );
p.addFieldContainsText( "3-7-14", "address");
p.addFieldContainsText( "松屋デパートの裏", "station");
p.addFieldContainsText(  "月〜木: 7:00 〜 22:30", "opentime");
p.scrape();
}
catch(e){console.log(e)}
指定されたテキストを含む要素のうち、一番はじめに出てくる要素を基準にしてXPathが作られて、そのXPathのデータを元にして前回作ったWeb::Scraperのjavascriptバージョンwebscraper.jsでページからデータが取り出すしくみになっています。
webscraperp result

ルールを取り出す

WebScraperPはaddFieldContainsTextされた要素をもとにてきとうなXPathを生成しているわけですが、そのXPathはgetWebScraperRule()で得らるので、これをJSONの文字列にして保存しておけば次回はWebScraperPなしでWebScraperにこのJSONを渡すことでデータを取り出すことができます。
WebScraperP JSON rule

Web::Scraperのコードにする

でもやっぱりブラウザ上で動かすのは不便なときもあるよね、ということで、同じことをWeb::Scraperでするためのperlのコードを出力するメソッドもつけました。

try {
var p = new WebScraperP(document);
p.addFieldContainsText( "銀座松屋通り店", "name" );
p.addFieldContainsText( "3-7-14", "address");
p.addFieldContainsText( "松屋デパートの裏", "station");
p.addFieldContainsText(  "月〜木: 7:00 〜 22:30", "opentime");
var code = p.getWebScraperPerlCode();
copy(code);
}
catch(e){console.log(e)}
取り出したい要素を追加したあとでgetWebScraperPerlCode()を呼ぶと
use URI;
use Web::Scraper;
my $scraper = scraper {
  process '//div[contains(concat(" ",@class," "),concat(" ","Table01"," "))]',
    'paragraphes[]' => scraper {
      process '//strong',
        'name' => 'TEXT';
      process '//tr[2]//p',
        'address' => 'TEXT';
      process '//tr[4]//td[2]',
        'station' => 'TEXT';
      process '//tr[5]//p[1]',
        'opentime' => 'TEXT';
    };
};
my $result = $scraper->scrape( URI->new("http://www.starbucks.co.jp/search/result_store.php" ) );
こうなって帰ってくるのでそのままperlのスクリプトにはって使ってもいいです。


ほかはebay検索結果とYahoo!電話帳 検索結果でしか試していませんが、いい感じで動いています。

XPathの可読性とその必要性

今回はXPathの生成部分で手を抜いているので、近接位置(proximity position)を使ったわりとHTMLの変化に対して弱いXPathが生成しています。proximity positionを使ったXPathは、数字で何番目に現れる要素かを指定しているので人間にとって非常に理解しづらいXPathになりますし、またHTMLが変化して要素の数がひとつずれただけでもデータを正しく取り出せなくなります。

でもXPathを生成するときに、変化に対して強く、人間にとっての可読性が高いXPathを生成するのは困難です。XPathのロケーションステップごとに可読性の評価を行ってその和が小さい/大きいでXPathを生成する関数を作るのは楽ではありませんし、そもそも人間にとってどういう記述が読みやすいのかを定義するのはたいへんな作業になります。そうやって可読性の高いXPathを生成できるようになったとしても、そもそもターゲットにしているHTML自体にclassやidが設定されていないとやはりproximity positionを使ったXPathを生成することになります。


今回のように自動で生成したXPathをスクリプトに渡すときに、生成されたXPathに可読性が必要でしょうか。XPathの可読性は、それを人間が読んで編集、修正する可能性があるときには必要ですが、人間が編集することがなく、スクリプトがそれを評価するだけであれば必要ありません。生成されたXPathで生成されるデータが正しいものであることを確認できるようにテストを組み、テストが失敗したときにはXPathを生成するプログラムを修正し、正しいXPathを生成させるような体制があって人間がXPathを直接みる必要性をなくせばXPathに可読性がある必要はなくなります。

ちょうど、人間にとって理解しやすく表現力の高いプログラミング言語で記述した処理を、コンパイラが解釈して生成する機械語に可読性を求められないのと同様、XPathをとりまくまわりの環境が整っていれば自動生成されるXPathに可読性は必ずしも必要ないのかなと感じます。

tags

  • XPath
  • data
  • javascript
  • 「XPathをてきとうに作ってくれる機能を追加したwebscraperp.js」のはてなブックマーク数
  • 「XPathをてきとうに作ってくれる機能を追加したwebscraperp.js」deliciousブックマーク数
  • 「XPathをてきとうに作ってくれる機能を追加したwebscraperp.js」をはてなブックマークに追加
  • save "XPathをてきとうに作ってくれる機能を追加したwebscraperp.js" to del.icio.us
  • 「XPathをてきとうに作ってくれる機能を追加したwebscraperp.js」をリアルタイムブログ検索
  • permalink
  • Codaで秘密鍵を使ってSFTPでサーバにアクセスする方法
  • いまさら人に聞けない Firebug tips

comments

TypeKey Enabled
スタイル用のHTMLタグが使えます。
*required

trackbacks

トラックバック元エントリにこのエントリへのリンクがない場合はトラックバックを受け付けません。

http://labs.gmo.jp/mt/mt-tb.cgi/203
©2010 Kentaro Kumagai, GMO Internet Labs., GMO Internet, inc.
bits and bytes
2008 .02. 20 18:07

tagcloud

  • API1
  • C/C++2
  • E4X1
  • FUSE2
  • Firefox19
  • HTML4
  • IE1
  • MySQL1
  • OSX4
  • Opera2
  • PHP4
  • XML1
  • XPCOM4
  • XPath3
  • apache2
  • binary2
  • book1
  • data11
  • debug5
  • design1
  • experiments3
  • extension10
  • google gears1
  • google maps API1
  • greasemonkey3
  • httpd5
  • javascript17
  • linux1
  • logging2
  • mobile3
  • perl4
  • tips5
  • tool11
  • vim2
  • visualization2
  • widget1
  • wii1
  • windows7
  • サービス6
  • 和訳1

Archives

  • 2008.03 (1)
  • 2008.02 (6)
  • 2008.01 (3)
  • 2007.12 (4)
  • 2007.11 (5)
  • 2007.10 (4)
  • 2007.09 (4)
  • 2007.08 (4)
  • 2007.07 (8)
  • 2007.06 (7)
  • 2007.05 (4)
  • 2007.04 (5)
  • 2007.03 (6)
  • 2007.02 (4)
  • 2007.01 (6)

about

  • bits and bytesのXML
  • 「bits and bytes」のCreative Commons
  • Powered by Movable Type
  • イベントと地図 - モグ
  • Use ecto to blog!
  • bits and bytesのはてなブックマーク数
  • bits and bytesをMy Yahoo!に追加
  • Subscribe with Bloglines