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

paiza開発日誌

paiza(https://paiza.jp)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

Twitterの過去ログが全部取得できず困った時に無料で解決できる方法

プログラミング 開発ネタ

f:id:paiza:20161205150517j:plain Photo by PROAndy Melton

f:id:paiza:20151217152725j:plainこんにちは、吉岡(@)です。

最近、Twitterの仕様変更により、Webサイト上に設置されているツイートボタンのツイート数が表示されなくなったことが大きな話題になりました。ツイート数がわからなくなったことにより、現在はそのページがどれだけTwitterでシェアされているかを確認することができなくなっています。

過去のツイートを確認するためには、ブラウザ上でTwitterサイトで検索することもできますが、整理や統計的な処理を行うにはそのままでは活用が難しい部分もあります。Twitterはほとんどの操作に対してAPIを提供しており、過去のツイートの検索もプログラムから行うことも可能ですが、一週間以上前のツイートを取得することはできません。

以前は、Twitterのデータを解析するサービスがいくつか提供されていましたが、現状、簡単に利用出来るサービスは存在しません。最近では、Twitterボタン仕様変更により、特定のキーワードを含むツイート数の取得も難しくなっています。

そこで、指定したキーワードで、定期的にツイートを保存する方法を考えてみることにしました。後から任意のキーワードで検索することはできませんが、自社の製品・サービスなどのツイートを確認するには十分だと思います。

今回は、設定したキーワードでのツイート検索結果をGoogleスプレッドシートに保存する方法を考えてみたのでご紹介していきます。Googleスプレッドシートはブラウザ上で気軽にデータを共有でき、統計処理、グラフ作成、外部サービス連携もできますので、ツイートの解析には便利です。

取得結果の例はこのようになります。

f:id:paiza:20151217150248p:plain

それでは実際に設定を行ってみましょう。手順としては以下のようになります。

スプレッドシートの作成

Googleスプレッドシートを作成します。

Google Apps Scriptの作成

続いて、Google Apps Scriptを作成します。

  • スクリプトの作成

    スプレッドシートのメニューから「ツール」=「スクリプトエディタ...」を選択することで、スクリプトエディタを起動します。

  • ライブラリの読み込み

    Twitter APIとの連携に必要なOAuth1ライブラリを読み込みます。 メニューから「リソース」=「ライブラリ...」を選択し、「ライブラリを検索」欄に 「Mb2Vpd5nfD3Pz-_a-39Q4VfxhMjh3Sh48」と入れて、選択ボタンを押します。 バージョンは最新(現在11)を選択しておきます。

f:id:paiza:20151217150435p:plain

TwitterAPIキー取得

Twitterの検索APIを利用するには、TwitterAPIキーが必要になります。 これは以下の手順で行います。

  • Twitterアプリケーション管理ページを開く

    https://apps.twitter.com を開きます。

  • Twitterアプリケーション作成

    「Create New App」ボタンでTwitterアプリケーションを作成します。 適当な名前、内容、ウェブサイトを設定します。

  • Callback URLの設定

    「Callback URL」に以下のURLを指定します。

  https://script.google.com/macros/d/[Google Apps Scriptプロジェクトキー]/usercallback

「[Google Apps Scriptプロジェクトキー]」は、Google Apple Scriptのスクリプトを開いた状態で、URLの"macro/d/"の後の部分で確認するか、メニューから「ファイル」「プロジェクトのプロパティ」で確認します。

  • APIキーの取得

    Twitterアプリケーションが作成できたら、アプリケーションページの"Keys and Access Tokens"にて "Consumer Key (API Key)"と"Consumer Secret (API Secret)"でAPIキーを確認します。

f:id:paiza:20150706115258p:plain

Google Apps Scriptの編集

作成したGoogle Apps Scriptを編集します。

スクリプト中の「XXXXXXXXXX-YOUR-CONSUMER-KEY-XXXXXXXXXX」、「XXXXXXXXXX-YOUR-CONSUMER-SECRET-XXXXXXXXXX」は先ほど取得したAPI Key, API Secretで置き換えてください。 また、「searchTerm」変数には検索したいキーワードを指定します。

// A Google Apps Script to download Twitter search results and save to the spread sheet.
// Ref:
//   Export Tweets from Twitter with Google Apps Script
//     http://ctrlq.org/code/19807-export-twitter-tweets
//   Google Apps ScriptでOAuthConfigのサポートが終了してTwitter botが危険そうだったので変更
//     http://kijtra.com/article/twitter-api-for-google-apps-script-without-oauthconfig/
//

var consumerKey = "XXXXXXXXXX-YOUR-CONSUMER-KEY-XXXXXXXXXX";
var consumerSecret = "XXXXXXXXXX-YOUR-CONSUMER-SECRET-XXXXXXXXXX";

var searchTerm = "paiza";

/* Add the tweet details into the sheet */
var logTweet = function(tweet) {
  var log = [];
  
  log.push(new Date(tweet.created_at));
  log.push(tweet.id_str);
  log.push(tweet.user.screen_name);
  log.push('=HYPERLINK("https://twitter.com/' + tweet.user.screen_name + '/status/' + tweet.id_str + '","' + tweet.user.name + '")');
  log.push(tweet.user.followers_count);
  log.push(tweet.retweet_count);
  log.push(tweet.favorite_count);
  log.push(tweet.text.replace(/\n|\r/g, " "));
 
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
  sheet.appendRow(log);
}

var downloadTweets = function(searchTerm) {
  var twitterService = getTwitterService();
  if (!twitterService.hasAccess()){
    throw new Error("Open " + twitterService.authorize() );
    return false;
  }
  
  var props = PropertiesService.getScriptProperties();
  var sinceID = props.getProperty("SINCEID") || "";

  var api = "https://api.twitter.com/1.1/search/tweets.json?count=100&include_entities=false" +
            "&result_type=recent&q=" + encodeURIComponent(searchTerm) + "&since_id=" + sinceID;
  var result = twitterService.fetch(api);
  var json = JSON.parse(result.getContentText()); 
  var tweets = json.statuses;
  
  for (var i = tweets.length - 1; i >= 0; i--) {
    logTweet(tweets[i]);
  }
  
  // SINCEID will store the ID of the last processed tweet
  if(tweets.length > 0){
    props.setProperty("SINCEID", tweets[0].id_str);
  }
}

var getTwitterService = function() {
  // Create a new service with the given name. The name will be used when
  // persisting the authorized token, so ensure it is unique within the
  // scope of the property store.

  return OAuth1.createService('twitter')
      // Set the endpoint URLs.
      .setAccessTokenUrl('https://api.twitter.com/oauth/access_token')
      .setRequestTokenUrl('https://api.twitter.com/oauth/request_token')
      .setAuthorizationUrl('https://api.twitter.com/oauth/authorize')

      // Set the consumer key and secret.
      .setConsumerKey(consumerKey)
      .setConsumerSecret(consumerSecret)

      // Set the name of the callback function in the script referenced
      // above that should be invoked to complete the OAuth flow.
      .setCallbackFunction('authCallback')

      // Set the property store where authorized tokens should be persisted.
      .setPropertyStore(PropertiesService.getUserProperties());
}

function authCallback(request) {
  var twitterService = getTwitterService();
  var isAuthorized = twitterService.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('Authorization Success! You can close this tab.');
  } else {
    return HtmlService.createHtmlOutput('Authorization Denied. You can close this tab');
  }
}

function run() {
  downloadTweets(searchTerm);
}

getTwitterService() 関数では、Twitter認証に必要な情報を設定しています。

downloadTweets() 関数では、Twitterの検索API(https://api.twitter.com/1.1/search/tweets.json)を呼び出しています。最後にダウンロードしたツイートのTweet IDをスクリプトプロパティに"SINCEID"変数に保存しておき、次回以降はそのID以降のツイートをダウンロードします。 スクリプトプロパティの内容はメニューの[ファイル]=[プロジェクトのプロパティ]で確認できます。

logTweet()関数では、取得したツイートをスプレッドシートに保存します。

Twitter認証情報を取得

まず、関数「run」を選択してスクリプトを実行します。

f:id:paiza:20151217150845p:plain

スクリプトの初回実行時には承認を求められますので、「続行」を選択します。

f:id:paiza:20151217150645p:plain

また、初回実行時は、まだTwitter認証情報が取得できていないので、以下のように「Open [URL]」として表示されたURLを開きます。

f:id:paiza:20151217150515p:plain

Twitterの認証画面が表示されますので、ログイン・許可を行います。成功すると「Authorization Success! You can close this tab.」とブラウザで表示されます。

f:id:paiza:20151217150528p:plain

失敗した場合、スクリプト中の「consumerKey」、「consumerSecret」が合っているか、Twitterのアプリケーション設定でcallback URLが正しく「https://script.google.com/macros/d/[Google Apps Scriptプロジェクトキー]/usercallback」に設定されているか、などを確認してください。

■ツイートの取得

認証情報も取得できたので、いよいよ実際にツイートを取得します。 関数「run」を選択して、再度スクリプトを実行します。 実行が終了すると、取得したツイートがスプレッドシートに表示されます。2回目以降は、前回の続きのツイートが追加されていきます。

検索キーワード変更などで取得し直す場合、スプレッドシートの内容を削除します。スクリプトプロパティに保存されている"SINCEID"変数を削除するため、スクリプトメニューの[ファイル]=[プロジェクトのプロパティ]を開き、[スクリプトのプロパティ]タブで"SINCEID"変数を削除します。その後スクリプトを実行すると、再度一から検索結果を取得できます。

f:id:paiza:20151217150735p:plain

■ツイート取得の定期実行

定期的に実行するため、スケジュール設定を行います。 Google Apps Scriptのメニューから[リソース]=[現在のプロジェクトのトリガー]を選択します。

f:id:paiza:20151217150934p:plain

「トリガーが設定されていません。今すぐ追加するにはここをクリックしてください。」をクリックしてトリガーを設定します。関数「run」を選択し、イベント「時間主導型」を選択します。更新頻度は、例えば10分ごとにしておきます。

f:id:paiza:20151217150914p:plain

「通知」をクリックすることで、スクリプト失敗時にメールで通知が送ることもできます。

■まとめ

以上のように、100行程度のスクリプトを書くことで、Twitterの検索結果をGoogleスプレッドシートに保存することができるようになりました。

Google Apps Scriptを用いることで各種サービスをつなぎ合わせて様々な操作を柔軟に自動化することができます。今回のスクリプトも、特定の条件に一致したツイートを抽出することや、HipChat、Slack等のAPIと連携することなどもできます。またスプレッドシートに対して、外部からSQL等でクエリを実行することもできます。ぜひ色々試してみてください。

■参照




paizaではITエンジニアとしてのスキルレベル測定(9言語に対応)や、プログラミング問題による学習コンテンツ(paiza Learning)を提供(こちらは21言語に対応)しています。テストの結果によりS,A,B,C,D,Eの6段階でランクが分かります。自分のプログラミングスキルを客観的に知りたいという方は是非チャレンジしてみてください。

http://paiza.jp




プログラミング入門講座|paizaラーニング

PHP入門編Ruby入門編Python入門編Java入門編JavaScript入門編C言語入門編C#入門編アルゴリズム入門編