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本
ピアソンエデュケーション
売り上げランキング: 4859

正しいプログラミングを学べる
読んで、理解して、実践できれば、一人前
中級以上なら必須のマナー
Javaの良書
