- 追加された行はこの色です。
- 削除された行はこの色です。
[[FrontPage]]
*Java:jerichoを使ってHTMLをパースする [#hb52f50c]
Rhino+JQueryでHTMLをスクレイピングしようと考えていたんだけど、Rhino+JQueryだとどうも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