kano

TwitterAPI 1.1でリツイートランキングを作る

TwitterAPI1.1に移行してしばらく経ちますが、今までと違って色々便利になった部分や
不便になった部分など色々あったのでポストしておきます。

■API 1.1

API1.1になってからはどのAPIを使用するにもアプリ経由でアクセスさせる必要があります。
例えば特定のワードで検索する場合、今まではsearchのURLにGETで検索するワードを投げるだけ、というお手軽仕様だったのですが、
参考:Search API (ツイートの検索)
1.1からはアプリ経由でoauth認証させてからAPIを叩く必要があります。

・PHP
twitteroauth - GitHub
参考ページ:Twitter API 1.1 を使用してPHPでつぶやきの検索結果を取得したときのメモ

・JavaScript
oauth.js
参考ページ:JavaScriptでOAuth認証を使ってTwitterのTimeLineを表示する

(JSはソース内にAPIキーなどを直書きする必要があり、丸見えになってしまうので、使用には注意が必要です。)

■アクセス制限(レートリミット)

以前は、検索のAPIは(誰でもアクセスできるという事もあってか)アクセスした個人のIPアドレス単位での制限、でした。
しかし、oauth認証が必須になり、IPアドレス単位、ではなく、アカウント単位、になりました。

例えば検索APIは、15分に180回、がリミットです。
単純にとあるワードで検索したタイムラインを表示するページを作成したとして、15分の間に180人の人がアクセスするとその時点で制限に引っかかってしまい、表示できなくなってしまいます。
こういう検索などで不特定多数が見るようなものはこの制限はかなり厳しくなったといえます。
(ツイートの見た目の規約などもきびしくなったので、こういうものは公式のウィジェットを使いなさい、って事かもしれません)

レートリミットについては、これまでIPアドレス単位であったのが、REST APIと同じくアカウント単位となります。 - 結局、Twitter API 1.1で何が変わる? 5つのポイント

しかし、特定の条件を満たした状態でなら、このリミットを緩和させる方法もありました。
検索が一番顕著で、15分180回から、15分450回に緩和されます。
それが、application-only authでの認証、というものになります。
参考:TwitterAPI1.1 application-only auth を使って検索結果制限を約3倍に増やす方法

公式の一覧表 REST API v1.1 Limits per window by resource

ちなみに、検索結果のヘッダに、検索の残り回数とリセットされる時間などが含まれています。

X-Rate-Limit-Limit : 使用回数 X-Rate-Limit-Remaining : 使用残り回数 X-Rate-Limit-Reset : 使用回数リセット時間 - REST API Rate Limiting in v1.1

■検索数上限

1回の検索数の上限は、100、です。
以前のAPIではページ数を指定出来るようになっており、最大の検索数で何ページ結果があるか、という値も取れたのですが、1.1からはそのページ数表記もなくなりました。

なので、100件より過去分を取得しようとすると、max_id、を指定する、という方法になります。

Returns results with an ID less than (that is, older than) or equal to the specified ID. - GET search/tweets

このIDを指定して検索すると、(そのIDを含む)そのIDより古いツイートを検索してくれます。
なので、100件取得、一番古いツイートのIDを使って再度検索。100件取得、、、という流れでどんどん過去にさかのぼって取得できます。
参考:twitter search apiを使って画像アリのツイートを拾ってみた

ちなみに、過去分は、約8日分取得出来るようです。

max_idの指定が8日前くらい遡り指定しても取得できるため、 「バルス」のように一度に大量にツイートがあっても取得することができます。 - Twitter検索API v1.1を調査したらスゴすぎて世界が広がった

■リツート

リツイート数は、searchAPIのJSON内に、retweet_countという値があるのでそのままランキング作成に使用できます。

検索で引っかかったリツイートしたツイート、は、本文がRTで始まる仕様になっています。

RT @ユーザー名: 本文

なので、そのままツイートやユーザー名を表示すると、リツイートした人の名前、そして、RTがついた本文、という表示になってしまいます。
(初めはこれは非公式RTかと勘違いしてしまいました)

しかしこれもJSON内にちゃんと記述されており、リツイート元のオリジナルのツイートの情報も含まれています。
それが、retweeted_status、の中の情報、となります。

取得したJSONデータを$result、とすると、以下のような形でオリジナルツイートの内容を取得出来ます。

項目 コード
ツイートID $result->retweeted_status->id_str
名前 $result->retweeted_status->user->name
スクリーンネーム $result->retweeted_status->user->screen_name
プロフィール画像 $result->retweeted_status->user->profile_image_url
本文 $result->retweeted_status->text
ツイート日時 $result->retweeted_status->created_at

この内容を使う事でオリジナルツイートを表示する事が出来ます。
あとは、リツイートされているほど、同じツイートが複数引っかかってくるので、重複分を除外していくことでオリジナルツイートのみを取得する事が出来ます。

■まとめ

ということで、参照ばかりで参考コードがなくて恐縮ですが、流れをまとめると以下のようになると思います。

  1. aouthで認証
  2. searchAPIで検索
  3. 検索結果の最後のIDを使用して任意の数になるまで過去分を取得
  4. idから重複しているツイートを除外
  5. retweet_countでソートしてランキングを作成

3では、任意の数になるまで過去分を取得する、とありますが、これは多くしすぎると取得に時間がかかってしまうのと、APIの消費が早くなってしまうので注意が必要です。
また、searchAPIを叩く際に、オプションで、result_typeをmixedに指定してやると、リツイート数やお気に入り数の多いツイートなど、ポピュラーと判断されたツイートも取得出来るようになります。

このresult_typeは以下の3つ指定出来ます。(デフォルトはmixed)

* mixed: Include both popular and real time results in the response. * recent: return only the most recent results in the response * popular: return only the most popular results in the response.

(popularにすると、ポピュラー分しか取得出来ないので注意)

思ったよりメモ的な内容となってしまいましたが、以上です。

おまけ

今回初めて知ったのですが、JSで日付を扱う場合、以下のような書式にしてしまうとChrome以外のブラウザではエラーになってしまうようです。

new Date(2013-08-22 12:11:45);

日付を「-(ハイフン)」で区切っている事が原因で、これを「/(スラッシュ)」にしてやると上手く扱えるようになりました。

new Date(2013/08/22 12:11:45);

データベースからDATETIME型で取得するとハイフン区切りになっているので注意が必要です。

参考:JavaScriptでDateを扱う際の注意点

お問い合わせはこちら