Java:jerichoを使ってHTMLをパースする
Last-modified: 2013-08-24 (土) 02:14:21 (3898d)
Top / Java:jerichoを使ってHTMLをパースする
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
これは便利。
外部リンク †
最初にこの記事を読みました。