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

Java:jerichoを使ってHTMLをパースする の変更点

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

[[FrontPage]]

*Java:jerichoを使ってHTMLをパースする [#hb52f50c]

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

なんか、HTMLだけじゃなくて、XMLのパースも出きるみたいです。
-[[Rhino:jQueryでメモリリーク?]]

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

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

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

-http://sourceforge.net/projects/jerichohtml/files/

ちなみに、公式ページはこちら
-http://jericho.htmlparser.net/docs/index.html

JavaDocはこちら
-http://jericho.htmlparser.net/docs/javadoc/index.html

***ソースコード [#q7c72ceb]
当ページの一覧ページからコンテンツページのリンク(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

これは便利。

***外部リンク [#ld83ddcc]
最初にこの記事を読みました。
-http://d.hatena.ne.jp/talisker_ZQN/20100801/1280651267