Jericho HTML Parserライブラリを利用してHTMLをパースする方法。

JavaでHTMLをパースする方法は色々ある。 前回 は、JavaAPIである ParserDelegatorを利用してHTMLをパースする方法を掲載した。 今回は、オープンソースソフトウェアである Jericho HTML Parser を利用してHTMLをパースしてみよう。 今回利用するライブラリのjarファイル名は、jericho-html-2.3.jarである。 本家サイト から ダウンロード することも出来るし、mavenを利用しているなら pom.xml へ下記の dependency を追加することで取得可能である。 依存関係に悩みたくないので、筆者ならmavenを利用する。

pom.xml

<dependency>
	<groupId>net.htmlparser</groupId>
	<artifactId>jericho-html</artifactId>
	<version>2.3</version>
</dependency>

さて、今回解析してみるHTMLファイルは以下の通りである。

hoge.html

<html>
<p>aaaaaaaaaaa</p>
<form name="form1" action="hogeAction">
<p>form1のPタグ1</p>
<input name="text1" type="text" value="value1" /><br>
<input name="text2" type="text" value="value2" /><br>
<input name="hidden1" type="hidden" value="value3" /><br>
<input name="hidden2" type="hidden" value="value4" /><br>
<input name="submit1" type="submit" value="value5" /><br>
<input name="submit2" type="submit" value="value6" /><br>
<p>form1のPタグ2</p>
</form>
<a href="link1.html">link1</a>
<a href="link2.html">link2</a>
<p>ccccccc
<p>
<table>
	<tr>
		<td>table1 row=0, col=0</td>
		<td>table1 row=0, col=1</td>
	</tr>
	<tr>
		<td>table1 row=1, col=0</td>
		<td>table1 row=1, col=1</td>
	</tr>
</table>
<table>
	<tr>
		<td>table2 row=0, col=0</td>
		<td>table2 row=0, col=1</td>
	</tr>
	<tr>
		<td>table2 row=1, col=0</td>
		<td>table2 row=1, col=1</td>
	</tr>
</table>
<!-- getElementByIdで取得できるように、id属性を指定。-->
<p id="hogeId">ほげ。</p>
</html>

このHTMLを解析して、タグを取り出すサンプルソースコードは以下の通り。

JerichoHtmlExample.java

package net.inuwasi.examples.htmlparser;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

import au.id.jericho.lib.html.Element;
import au.id.jericho.lib.html.FormControl;
import au.id.jericho.lib.html.HTMLElementName;
import au.id.jericho.lib.html.MasonTagTypes;
import au.id.jericho.lib.html.PHPTagTypes;
import au.id.jericho.lib.html.Source;

/**
 * Jericho HTML Parserを利用してタグを取得するExample
 */
public class JerichoHtmlExample {

    public static void main(final String[] args) {
        // タグタイプを登録
        PHPTagTypes.register();
        MasonTagTypes.register();

        try {
            new JerichoHtmlExample().process("./hoge.html");
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 実行してみる。
     * 
     * @param urlStr URL文字列
     * @throws IOException
     */
    private void process(String urlStr) throws IOException {

        // URLからSourceクラスを作成
        Source source = new Source(new FileInputStream(new File(urlStr)));

        //
        // 全ての a タグを取得してみる。

        System.out.println("\naタグを抽出。");
        List<Element> atags = source.findAllElements(HTMLElementName.A);
        for (int i = 0; i < atags.size(); i++) {
            Element e = (Element) atags.get(i);
            // href属性取得
            String href = e.getAttributeValue("href");
            // extractText取得
            String txt = e.getContent().extractText();

            // 出力
            System.out.println(String.format("href=%s, extractText=%s", href,
                    txt));
        }

        //
        // 全ての form コントロールタグを取得してみる。

        System.out.println("\nformコントロールタグ(inputとか)を抽出。");
        List<FormControl> controls = source.findFormControls();
        for (int i = 0; i < controls.size(); i++) {
            FormControl c = controls.get(i);
            // name属性取得
            String name = (String) c.getAttributesMap().get("name");
            // type属性取得
            String type = (String) c.getAttributesMap().get("type");
            // value属性取得
            String value = (String) c.getAttributesMap().get("value");

            // 出力
            System.out.println(String.format("name=%s, type=%s, value=%s",
                    name, type, value));
        }

        //
        // tableから特定のセルを取得してみる。
        // ※ここでは、0番目のtableの、0番目のtrの、0番目のtdのextractTextを取得します。

        System.out.println("\ntableから特定のセルを取得。");
        // 0番目のtableを取得
        Element table = (Element) source.findAllElements(HTMLElementName.TABLE)
                .get(0);
        // 0番目のtableの、0番目のtrを取得
        Element tr = (Element) table.findAllElements(HTMLElementName.TR).get(0);
        // 0番目のtableの、0番目のtrの、0番目のtdを取得
        Element td = (Element) tr.findAllElements(HTMLElementName.TD).get(0);
        // 出力
        System.out.println("extractText(table:0, tr:0, td:0)="
                + td.extractText());

        //
        // idを指定して特定のElementを取り出してみる。

        System.out.println("\nidを指定してpタグを取得。");
        // id属性を指定してelementを取得
        Element e = (Element) source.getElementById("hogeId");
        // 出力
        System.out.println("hogeId.extractText=" + e.extractText());
    }

}

これを実行すると以下のように標準出力される。

aタグを抽出。
href=link1.html, extractText=link1
href=link2.html, extractText=link2

formコントロールタグ(inputとか)を抽出。
name=text1, type=text, value=value1
name=text2, type=text, value=value2
name=hidden1, type=hidden, value=value3
name=hidden2, type=hidden, value=value4
name=submit1, type=submit, value=value5
name=submit2, type=submit, value=value6

tableから特定のセルを取得。
extractText(table:0, tr:0, td:0)=table1 row=0, col=0

idを指定してpタグを取得。
hogeId.extractText=ほげ。

JerichoHtmlExample.javaの解説

Jericho HTML Parserライブラリは、要素の取得に便利なライブラリであり、 登場するクラスも少なく、とてもシンプルである。 主に登場するクラスは、SourceクラスとElementクラスの2つである。

利用方法

利用者は、まず、URLなどを引数に Source クラスのインスタンスを作成する。 作成した Source を元に Element (タグ要素)を取得する。 Elementが取得できれば、後は如何様にでもなろう。 属性を取得するもよし、テキスト(タグとタグに挟まれている文字列)を取得するもよし、 子Elementを取得するもよし。

このような素晴らしいライブラリを提供してくれている The Jericho HTML Parser project には心から感謝したい。

お薦めのJava本

Effective Java 第2版 (The Java Series)
Joshua Bloch
ピアソンエデュケーション
売り上げランキング: 4859
おすすめ度の平均: 5.0
5 正しいプログラミングを学べる
5 読んで、理解して、実践できれば、一人前
5 中級以上なら必須のマナー
5 Javaの良書

筆者お薦めの一冊。

金融のしくみは全部ロスチャイルドが作った (5次元文庫)

我々の生活に最も身近な存在であるはずの「お金」、しかし最も未知の部分が多い存在でもある。 本書を読めば、「お金の真実」を知る事が出来るかもしれない。