Webエンジニアの開発記

Webエンジニアの開発記録です。Java,SAStruts,jQuery,AmazonWebService,マッシュアップ。

DOMとSAXは違う。

DOMとSAXが違うということは、薄々感づいていたのですが、

意識することなくいろんなサイトのソースをコピペして、

スクレイピングしようとしていました。

 

ですが、やはりDOMとSAXの違いというのは、

小さくなさそうなのでちょっと調べてみました。

 

・技術者のためのXML再入門(10):XMLプログラミングのためのAPI - @IT

XMLデータを操作するAPIとして、現在下記の2つがデファクトスタンダードとして利用されている。

DOM (Document Object Model)  ツリー・ベースのAPI

SAX (Simple API for XML)    イベント・ベースのAPI

 

XMLデータを一気に読み込んで構文解析し、メモリ上にツリーを展開する(このツリーを「DOMツリー」と呼ぶ)。

DOMでは、このメモリ上に展開されたDOMツリーにアクセスしたり、要素を追加・削除することでXMLデータの構造を変更することができる。

 

先頭から順にXMLデータを読み込んでいき、“要素の開始”や“要素の終わり”といったイベントを生成、その都度アプリケーションに通知する。

アプリケーションはそれらのイベントを受け取ったときの処理を定義しておき、イベントを受け取ったときに呼び出されて処理を行う。

 

メモリー消費 DOM > SAX

アクセス DOM ランダム、SAX 一方通行

 

なるほどー。同じXMLの解析するにしても、根本の発想は全然違うんですね。

今まで自分がやろうとしていたのは、DOMの考え方。

レスポンスをDOM化して、DOMの中の場所を指定して、必要な情報を得る方法。

 

でも、スクレイピングでの使用を考えると、

DOMを操作することはないですよね。

XML全体を1回なめて、必要な情報を抽出すればいいわけだから、

SAXの方がメモリ消費が少ないからよさそう。

読み込み効率もいいみたいだし。

でもSAXはSAX向けのプログラミングを覚えないといけないんだね。

そこがちょっとめんどくさい。

 

あれ?

でも、XPathとかXQuery使うにはDOMツリーを構築する必要があるんじゃない?

JTidyはSAXじゃなくてDOM

前回SAXとDOMの違いを調べてみました。

昨日、JTidyでヤフーをDOM解析しようとしていたので、

JTidyはSAXとDOMのどちら?と思って調べたら、DOMでした。

 

JTidyの日本語サイトに書いてあること、

自分の直面している問題に対して、どストライクなんですよね。

↓↓以下、日本語おかしいですがGoogle翻訳しました。

『その場合は、HTML Tidy Java ポート、HTML 文法チェッカおよびかなりのプリンターです。その非 Java のいとこのようなその場合は不正と障害のある HTML をクリーンアップするためのツールとして使用できます。さらに、その場合は実際の html DOM パーサーを提供します。

HTML文法に不正があってもDOM解析してくれる。

っていう認識でいいんですよね?

ヤフーよりも簡単なHTMLをJTidyでDOM解析。

ヤフーのHTMLははっきり言って読みにくいです。

なのでまずはJTidyに慣れるために、

動作確認の意味も込めて、もっと簡単なHTMLを解析しましょう。

 

HTML サンプル で検索してでてきたのが↓↓こちら。

http://www.html-cool.com/samples/tryhtml_basic.html

 

上記サイトのHTMLをInputStreamとして下記のメソッドに渡しました。


            Tidy tidy = new Tidy();
            tidy.setQuiet(true);
            tidy.setShowWarnings(false);
            tidy.setForceOutput(true);
            Document tidyDOM = tidy.parseDOM(inputStream, null);

            System.out.println(tidyDOM.getElementsByTagName("script").getLength());
            System.out.println(tidyDOM.getElementsByTagName("body").getLength());
            System.out.println(tidyDOM.getElementsByTagName("form").getLength());

 

実行したところ、コンソールには

4
1
1

と出ました。

 

http://www.html-cool.com/samples/tryhtml_basic.htmlをブラウザで開いて、

ソースを見てみて欲しいのですが、

<script> タグは確かに4つあります。 ⇒ OK

<body> タグは2つ。 ⇒ ? ⇒ textareaタグ内はカウントされない模様 ⇒ OK

<form> タグは確かに1つあります。 ⇒ OK

 

なので、JTidyでのDOM構築に成功していると言えます。

また、気になる事がtidy#parseDOMしたときにエラーが出た場合です。

 

下記の画像のように、今回正常にDOM構築できたわけではなく、

3つほどエラーが出力されています。

f:id:tahkah0124:20131218005237j:plain

エラー内容は、「そのタグの位置おかしいよ」的なことです。

 

しかし、そのエラーが出た後に、

4

1

1

という結果が出ているので、

エラーが出たとしてもDOMは構築できた!ということです。

これが私が欲しかった結果でした^^

 

明日またヤフーの解析にチャレンジしてみます。