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

@thorikiriのてょりっき

@thorikiriがWebとかAndroidとかの技術ネタや本を読んだブログです

Twitter4JとJsoupでTwitterBot作ったら簡単だった

twitter

Twitter4JはTwitter APIJavaラッパです。すごく簡単にTwitterにポストしたり出来ます。Twitter4J - A Java library for the Twitter API
JsoupはJavaのHTMLパーサで、jQueryを使っているかのようにDOM操作を簡単に出来ます。jsoup Java HTML Parser, with best of DOM, CSS, and jquery
それから、URLの短縮には、TinyURLAPIを使いました。こちらを見れば簡単に出来ます。Twitter 短縮URL TinyURLのAPI

今回は、Jリーグ.jp(日本プロサッカーリーグ)のサイトのニュースJリーグ.jp(日本プロサッカーリーグ)をパースして、タイトルとURLをTweetします。

JsoupでTweetするデータを取得する

ターゲットするサイトのHTMLソースを眺めて、どんなセレクタにすれば良いのか考えます。そしたら、おもむろに実装します。

// 対象のURLに向けて接続し、getメソッドでDocument全体を取ってきます
Document document = Jsoup.connect("http://www.jsgoal.jp/news/jsgoal/").get();
// 本当に欲しい部分だけをselectで取ってきます
Elements elements = document.select("div#newsBody div#normal ul li");
List<NewsDto> newsList = new ArrayList<NewsDto>();
// 各要素をぶん回します
for (Element element : elements) {
    // アンカータグのhref属性を取ってきます
    String url = element.select("a").first().attr("href");
    // アンカー要素の文字列を取ってきます
    String title = element.select("a").first().ownText();
    NewsDto news = new NewsDto(title, "http://www.jsgoal.jp" + url);
    newsList.add(news);
}
return newsList;

TinyURLAPIでURLを短縮する

TinyURLAPIを叩きます。テキストとして短縮されたURLが帰ってくるっぽいので、それを取得します。本当はHTTPのステータスとかチェックして、成功したのか判定するのが良いと思うよ。

BufferedReader br = null;
try {
    // 本当はURLエンコードしないとダメだけど、今回はする必要ないURLである前提
    HttpURLConnection conn = (HttpURLConnection)new URL("http://tinyurl.com/api-create.php?url=" + url).openConnection();
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    // 短縮されたURLが1行のテキストとして戻ってくるので読みこむ
    String shortUrl = br.readLine();
    return shortUrl;
} catch  (Exception e) {
    // 適当な例外処理
    throw new RuntimeException(e);
} finally {
    // お約束の後処理IOUtil使えばもっと簡単
    if (br != null) {
        try {
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

今回、Tweetが140文字を超える場合のみだけ短縮するようにしたので、これが呼び出されるのは140文字オーバーの場合だけです。

Twitter4JでTweetする

手順としてはTwitterインスタンスを作って、Consumer情報とAccessTokenを設定して、ポストするだけです。簡単ですね。
ConsumerとAccessTokenについては、Twitter Developersでアプリケーションを作って、アプリの情報ページに乗ってるので、わからなかったらググりながらアプリを作って下さい。

// Twitterのインスタンスを取得する
Twitter twitter = new TwitterFactory().getInstance();
// Consumer keyとConsumer secretを設定する
twitter.setOAuthConsumer("xxxxx"/*Consumer key*/, "xxxxx"/*Consumer secret*/);
// AccessTokenを作って設定する
AccessToken accessToken = new AccessToken("xxxxx"/*Access token*/, "xxxxx"/*Access token secret*/);
twitter.setOAuthAccessToken(accessToken);
for (NewsDto news : newsList) {
    String tweet = news.toString();
    // StatusUpdateにTweet内容を突っ込む
    StatusUpdate status = new StatusUpdate(tweet);
    // updateStatusでつぶやく
    twitter.updateStatus(status);
    // 3秒待ってみる
    Thread.sleep(3000L);
}

という訳で、ものすごく簡単でしたね。今気がついたけど、RSSもあるからそっから取っても良かったね。ちゃんちゃん。

追記(2012.03.09 10:40)

@yusukey 様よりご指摘いただきました。

なるほど。確かに短縮されたURLになっているようなので、URL部分より、その他の所があんまり長くなってないことを気にするべきかもですね。