読者です 読者をやめる 読者になる 読者になる

The jonki

呼ばれて飛び出てじょじょじょじょーんき

JavaのjsoupでHTMLをパースしてみた

JavaのHTMLパーサであるjsoupを使ってみようと思い、以前書いた名言ボットをこれで描いてみた。これはPythonBeautifulSoupを使ってたけどJavaだとどうなるのかな、みたいな。

準備

ここからjsoup-1.5.2.jarをダウンロードして外部jarに突っ込んで終わり。

ソース

無駄にDOMを使ったものとCSSjQueryライクな方法の2種類で書いてみました。単純なパースに関しては好みでいいんじゃないかな。難しいことやってないから、あんまり良い比較になってないけどどっちも直感的に使えそうです。

import java.io.IOException;
import java.net.MalformedURLException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class JsoupTest {
	static String url = "http://www.meigensyu.com/quotations/index/random";

	//decorate tweets
	//return <text> [<author>]
	String decorate(String text, String author) {
		StringBuilder sb = new StringBuilder();
		sb.append(text);
		sb.append(" [");
		sb.append(author);
		sb.append("]");
		return sb.toString();
	}
	
	//Use DOM methods to navigate a document
	//http://jsoup.org/cookbook/extracting-data/dom-navigation
	String getTweetByDom(Document doc) {
		Element content = doc.getElementById("contents_box");
		Element meigen = content.getElementsByClass("meigenbox").first();
		String text = meigen.getElementsByClass("text").first().text();
		Element link = meigen.getElementsByClass("link").first();
		String author = link.getElementsByTag("a").first().text();
		
		return decorate(text, author);
	}
	
	//Use selector-syntax to find elements
	//http://jsoup.org/cookbook/extracting-data/selector-syntax
	String getTweetBySelectorSyntax(Document doc) {
		Element content = doc.select("div#contents_box").first();
		Element meigen = content.select("div.meigenbox").first();
		String text = meigen.select("div.text").first().text();
		Element link = meigen.select("div.link").first();
		String author = link.select("a").first().text();
		
		return decorate(text, author);
	}
	
	public static void main(String args[]){
		JsoupTest jtest = new JsoupTest();
		try {
			Document doc = Jsoup.connect(url).get();
			String tweet1 = jtest.getTweetByDom(doc);
			String tweet2 = jtest.getTweetBySelectorSyntax(doc);
			System.out.println(tweet1);
			System.out.println(tweet2);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

出力例

当たり前ですが同じ出力です。

恋人として男と女で違う点は、女は一日中恋をしていられるが、 男は時々しかしていられないという点だ。 [モーム]
恋人として男と女で違う点は、女は一日中恋をしていられるが、 男は時々しかしていられないという点だ。 [モーム]