CData Software Blog

クラウド連携のCData Software の技術ブログです。

Twitter Drivers : TweetStreamでリアルタイムツイートを取得する

こんばんは。CData Software Japanエンジニアの浦邊です。

本記事ではCData Twitter Driversを使って、リアルタイムに発せられるツイートデータを取得する方法を説明します。 CData Twitter DriversではTwitterのツイートデータを取得するテーブルとして以下の二つが用意されています。

  • Tweets : 認証ユーザのタイムラインにあるツイートのセットを取得する
  • TweetStream : すべての公開ツイートからランダムにサンプリングしたツイートをリアルタイムに取得する

どちらのテーブルでも今回目的とするリアルタイムツイートの取得は可能ですが、TweetStreamビューの方がより特化した機能を持っています。 以下からはTweetsテーブルの概要と課題を説明し、TweetStreamビューを利用したリアルタイムツイートの取得方法を説明します。

CData Twitter Drivers

CData Twitter Driversは以下からダウンロードできます。 Excel等のアプリケーションからツイートデータを扱いたい場合、以下から評価版をダウンロードしてお試しください。 https://www.cdata.com/jp/drivers/twitter/

Tweetsテーブル

Twitter DriversはTwitter APIに接続する際、与えられたユーザ認証情報をもとに認証を行います。Tweetsテーブルは認証ユーザのタイムライン上のツイートを取得します。通常のユーザの場合、取得するツイートの期間はデータ取得時点から7日間分ですが、プレミアムアカウントのユーザはさらに古いツイートを取得できます。Tweetsテーブルは通常のテーブルと同様に、データを取得するクエリの実行を契機としてAPIにリクエストを発行し、タイムラインデータのレスポンスが返された時点で処理は完了します。

f:id:urabe_shintaro:20210311182717p:plain

Twitterのタイムラインではキーワードで検索するとフォローしていないユーザを含めたツイートを取得できますが、Tweetsテーブルも同様に、以下のようにSearchTermsを指定することで公開ツイートから指定したキーワードを含むツイートを取得できます。

select * from Tweets SearchTerms = 'test'

リアルタイムツイート取得の課題

Tweetsテーブルで取得するツイートは、データ取得時点での最新ツイートから過去一定期間のツイートです。 常に最新のツイートを取得し続ける場合にはTweetsテーブルの取得を繰り返して行いますが、短時間で多くのリクエストを発行するとAPIレートリミットに違反してしまう可能性があります。

この課題を解決する機能を持つテーブルが次項で説明するTweetStreamです。

TweetStreamビュー

TweetStreamもツイートを取得するビューですが、Tweetsテーブルとの大きな違いとして以下の2点があります。

  • 認証ユーザのタイムラインではなくすべての公開ツイートを取得対象とします。ただし全公開ツイートから1%のツイートをランダムにサンプリングしたデータを取得します。
  • データを取得するクエリを発行するとリアルタイムツイートをレスポンスとして返します。ただし1つのレスポンスで完了せず、終了のトリガが発生するまでリアルタイムツイートをストリームとして返し続けます。

f:id:urabe_shintaro:20210311182729p:plain

1つのリクエストでツイートデータを取得し続けるためレートリミットを気にする必要がありません。 リアルタイムツイートの取得に特化したビューであると言えます。

それでは、このビューを利用したツイートストリームの開始方法と、さらに重要な終了方法について説明します。

ツイートストリームの開始方法

以下のようにTweetStreamにSELECT文を発行するとツイートストリームが開始されます。

select * from TweetStream

サンプルコード

CData JDBC Twitter Driverを使ったサンプルコードを示します。 以下のJavaコードはTweetStreamにアクセスし、公開ツイートの日時、アカウント名、ツイート内容、リツイート数、お気に入り数を取得します。 終了条件が設定されていないため、接続が強制的に切断されるまで延々とツイートを取得し続けます。

Connection conn = DriverManager.getConnection("jdbc:twitter:InitiateOAuth=GETANDREFRESH");
Statement stat = conn.createStatement();
boolean ret = stat.execute("SELECT Created_At, From_User_Name, Text, Retweet_Count, Favorite_Count FROM TweetStream");

if (ret) {
    ResultSet rs=stat.getResultSet();
    while(rs.next()) { // リアルタイムツイートを取得し続けるためループは終了しない

        Timestamp tweetDate = rs.getTimestamp(1); // ツイート日時
        String accountName = rs.getString(2);     // アカウント名
        String tweetContent = rs.getString(3);    // ツイート内容
        int retweetCount = rs.getInt(4);          // リツイート数
        int favoriteCount = rs.getInt(5);         // お気に入り数

        // 取得内容の表示
        System.out.println(tweetDate + "," + accountName + "," + tweetContent + "," + retweetCount + "," + favoriteCount);
    }
}

ツイートストリームの終了条件

開始されたツイートストリームはSQL等で明示的に終了させることはできません。 データソースへの接続を切断するか、終了条件を満たすことで終了します。

終了条件は以下の3つがあります。

  1. 一定数のツイートを取得
  2. ツイートの取得を開始してから一定時間経過
  3. ツイートが無い時間が一定時間経過

1. 一定数のツイートを取得

一定数のツイートを取得した時にストリームを終了させます。 この条件を指定するには、クエリにTOP句またはLIMIT句を付与します。 例えば100個のツイートを取得した時点でストリームを終了する場合、以下のようにtop 100を付与します。

select top 100 * from TweetStream;

2. ツイートの取得を開始してから一定時間経過

一定時間経過した後にストリームを終了させます。 この条件を指定するには、接続プロパティのStreamReadDurationプロパティに経過時間(秒)を設定します。 例えばツイートの取得開始から1分後に終了する場合、StreamReadDuration = 60と設定します。

3. ツイートが無い時間が一定時間経過

ツイートが無い状態が一定時間経過したことを契機にストリームを終了させます。 この条件を指定するには、接続プロパティのStreamTimeoutプロパティに経過時間(秒)を設定します。 例えばツイートが3分間途絶えたら終了する場合、StreamTimeout = 180と設定します。

StreamReadDurationプロパティとStreamTimeoutプロパティを組み合わせて使ったときの挙動を以下に例示します。 これらのプロパティは0を設定すると無視されます。

StreamReadDuration StreamTimeout 動作
0 0 時間では終了しない
30 0 30秒後に終了
0 10 ツイートが途絶えた10秒後に終了
30 10 30秒後に終了またはツイートが途絶えた10秒後に終了

終了条件を指定したサンプルコード

最初に示したサンプルコードに3つの終了条件を付与したコードを示します。 このコードは以下のいずれかの条件が満たされた時点でツイートの取得を終了します。

  • 10000ツイートを取得
  • データの取得開始から120秒が経過
  • ツイートが途絶えてから30秒が経過
Connection conn = DriverManager.getConnection("jdbc:twitter:InitiateOAuth=GETANDREFRESH;StreamReadDuration=120;StreamTimeout=30");
Statement stat = conn.createStatement();
boolean ret = stat.execute("SELECT TOP 10000 Created_At, From_User_Name, Text, Retweet_Count, Favorite_Count FROM TweetStream");

if (ret) {
    ResultSet rs=stat.getResultSet();
    while(rs.next()) { // 終了条件に合致したらループが終了

        Timestamp tweetDate = rs.getTimestamp(1); // ツイート日時
        String accountName = rs.getString(2);     // アカウント名
        String tweetContent = rs.getString(3);    // ツイート内容
        int retweetCount = rs.getInt(4);          // リツイート数
        int favoriteCount = rs.getInt(5);         // お気に入り数

        // 取得内容の表示
        System.out.println(tweetDate + "," + accountName + "," + tweetContent + "," + retweetCount + "," + favoriteCount);
    }
}

おわりに

今回はCData Twitter DriversのTweetStreamを使ったリアルタイムツイートの取得方法を説明しました。 CData Twitter Driversは30日間無料でお使いいただけます。 Twitter APIとの連携をご検討の方はぜひお試しください。