search_metadataによる連続取得
TwitterAPIは一度のリクエストで最大100件までしかツイートを取得できません。
例えば#ゲーム実況
というタグが付いたツイートを収集しようと思っても最新の100件を取得したらそこで次の取得を打ち切ってしまいます。
どうにかならないかということで調べてみたところ以下の記事がヒット。
Node.jsでTwitter検索から100件を超えるツイートを取得したい
詳細はリンクを参照してほしいのですが、以下のようなコードで連続取得が可能になります。
const Twitter = require('twitter');
const client = new Twitter({
consumer_key: "---",
consumer_secret: "---",
access_token_key: "---",
access_token_secret: "---"
});
const searchTweet = async function (maxId = null) {
let result = [];
const searchParam = {
q: "#ゲーム実況"
}
if(maxId){
searchParam['maxId'] = maxId;
}
const { statuses, search_metadata } = await client.get("search/tweets", searchParam );
result = result.concat(statuses);
// 次の取得対象ツイート存在チェック
if(search_metadata != undefined && search_metadata['next_results']){
maxId = search_metadata['next_results'].match(/\?max_id=(\d*)/)[1];
result = result.concat(await searchTweet(maxId));
}
return result;
}
以下のsearch_metadata['next_results']
に次のツイート情報が格納されており、それをパラメータで指定して再帰呼び出しを行うことで次の100件分ツイートを取得しています。
const { statuses, search_metadata } = await client.get("search/tweets", serachParam);
search_metadataがない場合の連続取得
このsearch_metadata
というものは全部のエンドポイントの戻り値にあるものではないようで、例えば特定のユーザの投稿内容を取得する場合はsearch_metadataを参照できません。
そんな場合はどうしたらいいんだ!と色々模索してごちゃごちゃした結果以下のように落ち着きました。
const getUserTimeline = async function(maxId = null) {
const searchParam = {
screen_name: "baito_san"
}
if(maxId){
searchParam['maxId'] = maxId;
}
let data = await client.get("statuses/user_timeline", searchParam);
if(data.length > 1){
// 1件目の取得結果を除外
data = searchParam ['max_id'] ? data.slice(1) : data;
const maxId = data.slice(-1)[0]['id_str'];
data = data.concat(await getUserTimeLine(maxId);
}
return data;
}
n - 1回目の取得結果の最後のツイート情報をn回目の検索パラメータのmaxIdに指定して連続取得しています。問題としてはn - 1回目の最後のツイートがn回目の取得結果の1件目に来てしまい、無駄に1件多く取得してしまっていることです。
他にうまいこと取得できる方法があればぜひコメントで教えてください。
あとがき
今回のコードを使って自分の過去ツイートを全件取得して出力してみたのですがなかなかに痛々しくて羞恥心を覚えました。皆さんも是非自分の過去ツイートを出力してみてください。
参考記事・ページ
Node.jsでTwitter検索から100件を超えるツイートを取得したい
Twitter 開発者 ドキュメント日本語訳