Web::Scraperのjavascriptバージョンwebscraper.js

perlのWeb::Scraperみたいな記述で、ページの中からデータを取り出すwebscraper.jsという小さなjavascriptのライブラリを書きました。

ブックマークレット

データを取り出したいページでブックマークレットでwebscraper.jsを読み込んでFirebugコンソールで使います。
ブックマークレット
webscraper
コード
webscraper.js

つかいかた

Web::ScraperのSYNOPSISで例としてあげられているebayでapple ipod nanoを検索した結果からデータを取り出すときは 検索結果ページで上のブックマークレットを呼び出してFirebugコンソールで取り出す部分を記述します。 こんなかんじ。
calling WebScraper.scrape in Firebug console
SYNOPSISのperlのコードで変数$ebay_auctionに一度代入されている部分をそのままインラインで書き直すと
my $ebay = scraper {
    process "table.ebItemlist tr.single",
            "auctions[]" => scraper {
                process "h3.ens>a",
                        description => 'TEXT',
                        url => '@href';
                process "td.ebcPr>span", price => "TEXT";
                process "div.ebPicture >a>img", image => '@src';
    };
    result 'auctions';
};
こうなります。Web::Scraperではページのどの部分を取り出すかの記述をDSLっぽいperlのコードで記述します。javascriptはperlのようにはコードの記述方法に自由さがないのでWeb::Scraperのように要素の記述をjavascriptの式で表現するのはあきらめて、JSONで記述することにしています。上のWeb::Scraperのperlのコード部分をJSONで
WebScraper(  {
    'table.ebItemlist tr.single': {
        'auctions[]': {
            'h3.ens>a': {
                    description: 'TEXT',
                    url: '@href'
            },
            'td.ebcPr>span': {
                price: "TEXT"
            },
            'div.ebPicture >a>img': {
                image: "@src"
            }
        }
    }
} ).scrape(document);
というふうに表現して書きます。

要素の指定にはWeb::Scraperと同様にCSSセレクタ、もしくはXPathを使います。CSSセレクタでの指定部分はLatest topics > selector.js改 - outsider reflexのselector.jsを使わせていただいています。

上のjavascriptの実行結果の中身は
javascriptのオブジェクトにWeb::Scraperと同じかたちで取り出したデータが入ります。

CSSセレクタとXPathの判別

両方書けるようにすると、書かれているのがCSSセレクタなのかXPathなのかを正しく判別するのがわりと難しい問題になります。

なぜならCSSセレクタの記述はXPathとしても正しい記述なものが多いからです。たとえばh1の子要素のaという意味の h1 > a というCSSセレクタは、"コンテキストノードの子要素のh1とaの中のテキストを数値に変換したときh1の中身のほうが大きいか"という意味の正しいXPath式として評価できます。そのため、単純にXPath式として正しくないものがCSSセレクタという判別ができません。

Web::Scraperはどうしているのかなーと思ってみたところ
        my $xpath = $exp =~ m!^(?:/|id\()! ? $exp : HTML::Selector::XPath::selector_to_xpath($exp);
というコードで、式のはじめが/かidのときはXPathという判別方法が使われていました。 webscraper.jsでは、もうちょっと柔軟にXPathが書けるように次のような方法を採ることにしました。
  1. document.createExpressionでXPath式として評価できるかを調べる。できなかったらCSSセレクタ
  2. \.\w+にマッチする文字列がクオートされていない部分にあったらCSSセレクタ
  3. [<+\->]にマッチする文字列が [ ] で囲まれていない部分にあったらCSSセレクタ
1番目は、たぶん細かいことをjavascriptでいろいろやるよりバイナリで実装されているdocument.createExpressionにかけたほうが速いだろうという気持ちで入れています。ここでNGなものは確実にXPathじゃないわけですし。

2番目の条件は、CSSセレクタでよく使われる . はAutoPagerize SITEINFOを見るとXPathではファイルの拡張子以外で使われていないので、クオートされていないところで . を使うような式はCSSセレクタとして書いたつもりの式だと判断するために入れました。

3番目の条件も同様にXPathでは <, +, -, > は演算子として [ ] の中に書くことがほとんどなので、[ ]の外側で使っていたらCSSセレクタだと思うことにしました。

予定

いまのところは現在のページのDOMからデータを取り出せませんが、GreasemonkeyやFirefox extensionと組み合わせてリモートのドキュメントからも取り出せるようにしたいと思っています。

tags

  • data
  • javascript
  • perl
  • 「Web::Scraperのjavascriptバージョンwebscraper.js」のはてなブックマーク数
  • 「Web::Scraperのjavascriptバージョンwebscraper.js」deliciousブックマーク数
  • 「Web::Scraperのjavascriptバージョンwebscraper.js」をはてなブックマークに追加
  • save "Web::Scraperのjavascriptバージョンwebscraper.js" to del.icio.us
  • 「Web::Scraperのjavascriptバージョンwebscraper.js」をリアルタイムブログ検索
  • permalink
  • Ningの再発見
  • Codaで秘密鍵を使ってSFTPでサーバにアクセスする方法

comments

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

trackbacks

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

http://labs.gmo.jp/mt/mt-tb.cgi/201
©2010 Kentaro Kumagai, GMO Internet Labs., GMO Internet, inc.
bits and bytes
2008 .02. 15 16:37

tagcloud

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

Archives

  • 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