Twitter4Jを使ってTwitterでの自分のツイートをすべて取得する。
といってもAPIで取得できるツイートは最新のツイートから3200個までらしいので、可能な限り取得するところまで。

6) There are pagination limits
Rest API Limit

Clients may access up to 3,200 statuses via the page and count parameters for timeline REST API methods. Requests for more than the limit will result in a reply with a status code of 200 and an empty result in the format requested. Twitter still maintains a database of all the tweets sent by a user. However, to ensure performance of the site, this artificial limit is temporarily in place.

Twitter API Wiki / Things Every Developer Should Know

環境: Eclipse + JRE6 + Twitter4J 2.1.1

Twitter4Jのインストール

1. Twitter4J - A Java library for the Twitter API にて twitter4j-2.1.1.zip をダウンロード。
2. twitter4j-2.1.1.zip を解凍して twitter4j-core-2.1.1.jar をクラスパスに追加。

ソースコード

max_id を指定して Twitter の Web API を複数回コールするやり方。
JavaのバージョンはJDK6相当を使用。


import java.util.*;
import twitter4j.*;
 
public class UserTimelinePrinter {
 
  public static void main(String[] args) throws Exception {
 
    String screenname = "nilab";
    String password   = "********";
 
    TwitterFactory factory = new TwitterFactory();
    Twitter twitter = factory.getInstance(screenname, password);
 
    // APIで1度に取得できるのは200ツイートまで
    // (でも実際には200も取得できない)
    final int count = 200;
    Paging paging = new Paging(1, count);
    long maxId = 0;
 
    // Web APIを可能な限り呼び出してツイートを取得
    while(true){
      ResponseList<Status> statusList =
        twitter.getUserTimeline(screenname, paging);
      if(statusList.size() == 0){
        break;
      }
      for(int i=0; i<statusList.size(); i++){
        Status s = statusList.get(i);
        // 一意なツイートID
        long id = s.getId();
        // ツイートの内容
        String text = normalizeText(s.getText());
        // 投稿日時
        Date created = s.getCreatedAt();
        // 位置情報
        GeoLocation geoloc = s.getGeoLocation();
        Double lat = null;
        Double lng = null;
        if(geoloc != null){
          lat = new Double(geoloc.getLatitude());
          lng = new Double(geoloc.getLongitude());
        }
        // 出力
        StringBuffer sb = new StringBuffer();
        sb.append("id=" + id + "\t");
        sb.append("text=" + text + "\t");
        sb.append("created=" + created + "\t");
        sb.append("lat=" + lat + "\t");
        sb.append("lng=" + lng + "\t");
        System.out.println(sb.toString());
      }
      // 1回のWeb APIコールで取得した最後のツイートのIDから1引いた値をmaxIdにセット
      // maxId以下(未満ではない)のツイートが取得対象なので
      // 1引いておかないと、今回の最後のツイートと、
      // 次のWeb APIコールの最初のツイートが同じものになる
      maxId = statusList.get(statusList.size() - 1).getId() - 1;
      paging.setMaxId(maxId);
    }
  }
 
  // ツイートに改行が含まれていた場合は半角空白文字に置き換える
  private static String normalizeText(String s){
    // to space
    s = s.replaceAll("\r\n", "\n");
    s = s.replaceAll("\n", " ");
    return s;
  }
}

APIコール1回で取得できるツイートの数は最大で200らしい。

count. Optional. Specifies the number of statuses to retrieve. May not be greater than 200. (Note the the number of statuses returned may be smaller than the requested count as retweets are stripped out of the result set for backwards compatibility.)

Twitter API Wiki / Twitter REST API Method: statuses user_timeline

実行結果

途中でエラーが出て終了した。


[Sun Apr 04 23:27:01 JST 2010]Using class twitter4j.internal.logging.StdOutLoggerFactory as logging factory.
id=11587466518	text=「男子が、打たれ弱い生き物だってことは肝に銘じておきましょう。」 http://event.movies.yahoo.co.jp/theater/solanin/general_basic_d11/index.php	created=Sun Apr 04 22:30:36 JST 2010	lat=null	lng=null	
(中略)
id=11579967915	text=完全禁煙のコメダ珈琲なんてはじめて見た。喫煙場所が入口付近になければ完璧なのに。 (@ コメダ珈琲) http://4sq.com/bVEJKG	created=Sun Apr 04 18:15:26 JST 2010	lat=35.245317	lng=136.936926	
id=11579905569	text=完全禁煙のコメダ珈琲なんてはじめて見た。喫煙場所が入口付近にさえなければ完璧なのに。 - Photo: http://bkite.com/45cbq	created=Sun Apr 04 18:13:00 JST 2010	lat=35.247611	lng=136.972224	
(中略)
Exception in thread "main" twitter4j.TwitterException: 502:Twitter is down or being upgraded.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="en-us" />
    <title>Twitter / Over capacity</title>
(中略)
  </body>
</html>
 
  at twitter4j.internal.http.HttpClient.request(HttpClient.java:325)
  at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:68)
  at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:82)
  at twitter4j.Twitter.getUserTimeline(Twitter.java:319)

自分の全ツイートの数が少なければエラーは出ないかも。
また、現時点ではAPIコール回数の制限が60分間に150回程度なので、ある程度の間隔をあけてAPIをコールする形にすればエラー出ないかも。

たしかAPIの制限量などを取得できるちょっとメタな雰囲気のAPIがTwitterから提供されていたはず。

tags: zlashdot Zura Java Twitter Twitter4J

Posted by NI-Lab. (@nilab)