トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

Java:jerichoを使ってHTMLをパースする

Last-modified: 2013-08-24 (土) 02:14:21 (3898d)
Top / Java:jerichoを使ってHTMLをパースする

FrontPage

Java:jerichoを使ってHTMLをパースする

Rhino+JQueryでHTMLをスクレイピングしようと考えていたんだけど、Rhino+JQueryだとどうもJQUeryオブジェクトのガベージができていないように見えて(メモリリークしているような感じ)、実用に耐えられない雰囲気だったので、違う方法を模索していたら、jerichoが良さそうだったので書いてみました。

jerichoなんか、HTMLだけじゃなくて、XMLのパースにも便利に使えるようです。

HTMLも不完全なものもちゃんとパースできるみたいです。

準備

以下のURLより、jerichoのアーカイブをDLして、「dist」ディレクトリに入っているjarをクラスパスに通します。

ちなみに、公式ページはこちら

JavaDoc?はこちら

ソースコード

当ページの一覧ページからコンテンツページのリンク(aタグ)だけ取り出して、コンテンツページの実際のコンテンツ(id="body")を出力するサンプルです。

HtmlParserSample?.java

package etc;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.Source;

public class HtmlParserSample {

	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws MalformedURLException 
	 */
	public static void main(String[] args) throws MalformedURLException, IOException {
		// TODO 自動生成されたメソッド・スタブ

		Source html = new Source(new URL("http://www.hiihah.info/index.php?cmd=list"));

		//XMLを相手にするなら下記を記述
		html.fullSequentialParse();
		Element body = html.getElementById("body");
		
		List<Element> aList = html.getAllElements("a");
		List<Element> targetList = new ArrayList<Element>();
		
		for (Element element : aList){
			if (isTarget(element)){
				System.out.println(element.getTextExtractor() + "\t" + element.getAttributeValue("href"));
				targetList.add(element);
			}
		}
		
		Source targetPage = null;
		for (Element element : targetList){
			targetPage = new Source(new URL(element.getAttributeValue("href")));
			System.out.println(targetPage.getElementById("body").getTextExtractor());
		}
	}
	
	/**
	 * 一覧ページのうち、コンテンツのリンクである場合はtrueを返却する。
	 * @param element
	 * @return
	 */
	public static boolean isTarget(Element element){
		if (element.getParentElement().getName() == "li" &&
				element.getParentElement().getParentElement().getName() == "ul" &&
				element.getParentElement().getParentElement().getParentElement().getName() == "li" &&
				element.getParentElement().getParentElement().getParentElement().getParentElement().getName() == "ul"
				){
			return true;
		}
		return false;
	}
}

いやー、ほんと簡単ですなw

これは便利。

外部リンク

最初にこの記事を読みました。