4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Web APIAdvent Calendar 2021

Day 18

Twitter API v2で大量(<100)のツイートを一度に取得する in PHP

Last updated at Posted at 2021-12-17

利用者の目線で、Twitter API v2を使ったツイート検索の実装例をPHPを使い紹介します。
一度に100件以上取得する際のPHPの実装例の記事がなかったのでAPI自体の仕様と共に軽く紹介します。(Pythonなどは有る)
Web APIアドベントカレンダーの18日目です!昨日17日目は@sugimomotoさんのMock API ライブラリ WireMock を使ってみたです。

Twitter API v2検索概要

Twitter API v2とは2020年8月にリリースされた新しいAPIです。
また、ちょうど先月の11月中旬にv2がデフォルトのAPIになり、v1.1からの移行が推奨されれています

主要PHPライブラリの対応状況

今回は主にPHPでの実装を中心にご紹介します。
最も有名なTwitter APIのライブラリである「TwittterOAuth」は今年の7月にバージョン3.0.0を公開してv2に対応しました。

(まぁエンドポイント変えるだけなので対応しなくても自力で出来ますがせっかくabrahamさんがやってくれたので恩恵を享受しましょう)

v2アプリを新規登録

v1.1の認証情報ではアクセスできず、新たにv2用のアプリを作る必要がありますが、既にDeveloper申請に合格している人は速攻発行可能です。
Developer Portalの左カラムからv2用のアプリケーションを登録できます。
スクリーンショット 2021-11-29 151440.png

ちなみにv1.1アプリの認証キーを使ってリクエストしたら、以下のように親切にv2への登録が必須ですよと登録URLと共に返却してくれます。優しい…(惚れ)

["detail"]=>
string(201) "When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer App that is attached to a Project. You can create a project via the developer portal."
["registration_url"]=>
string(55) "https://developer.twitter.com/en/docs/projects/overview"
// ︙

ツイート検索+100件以上取得

制限と2つのエンドポイント

エンドポイントの種類

v1.1ではPremiumプラン等の区分がありましたがv2では利用用途によります。

  • /2/tweets/search/recent … 過去1週間のツイートを取得
  • Full-archive search … 全ての期間のツイートを取得可能。学術研究の利用者限定

研究中の大学教員・Drに限るなどの制限があり、審査も有るので殆どの人は上段を使うことになります。

APIのリクエスト制限

使うアプリケーション認証とユーザー認証でレートリミットが変わるのもv1.1とほぼ同じです。

ユーザー認証 アプリケーション認証
リクエスト回数 180回 / 15分 450回 / 15分
1度の取得数 10~100件 10~100件

また、v2アプリ全体で1ヶ月あたり200万ツイートまでという月単位での制限も存在します。制限の状況はTwitter Deleloperのアプリページから参照出来ます。
rapture_20211218001600.png

実装例(サンプルコード)

以下にサンプルコードを示します。PHP 7.x or 8.xを使い、Composerライブラリを導入してください。

composer require abraham/twitteroauth

レートリミットの制限処理は通常は制限状況を取得して確認するのがいいのですが、今回は予めアクセスする回数を指定する方式で紹介します。制限の緩いベアラートークンを使用しています。
個人開発や取得が目的の場合なら、クライアント側でリクエストした回数を記録して150に行ったら止める…的な操作でも十分良いと思います。ちゃんとやりたい場合はv1.1とやり方は変わりませんのでDo It Yourself。

v2_search.php
<?php
require_once "vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;

$connection = new TwitterOAuth(
    "************************", // API Key
    "************************", // API Secret
    null,
    "************************" // ベアラートークン
);
$query = "キーワード";
// ここでAPIのバージョンを2に指定
$connection->setApiVersion("2");
$params = [
    /*
    参照:https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent
    ※queryとmax_resultは必須
    */
    "query" => $query . " -is:retweet", // RTを除外したい時
    "start_time" => "2021-12-12T00:00:00+09:00",
    "end_time" => "2021-12-03T00:00:00+09:00",
    "tweet.fields" => "created_at", // 今回は追加で投稿日時を指定
    "max_results" => 100 // 10~100の間を指定
];
// $req_countにリクエストの回数を設定・$loop_countにリクエスト回数を設定
$req_count = 0;
$loop_count = 400;

for ($i = 0; $i < $loop_count; $i++) {

    /* リクエスト制限時
    余裕を持って15分より長く、450回より短く設定しています。
    ここら辺の処理は各自皆さんでうまく対処してください。
    */
    if($req_count > 400){
        echo "制限 / 15分待機";
        $loop_count = 0;
        sleep(1000000);
    }
    // v2でリクエスト
    $request = $connection->get("tweets/search/recent", $params);
    // 取得情報を処理
    foreach ($request->data as $data) {
        // <ここでデータの処理をする>
    }
    echo "Success Request";
    // 100件以上ある場合
    if (isset($request->meta->next_token)) {
        echo $req_count;
        $req_count++;
        // クエリパラメータの配列にnext_tokenを追加
        $params["next_token"] = $request->meta->next_token;
    } else {
        // 無いときは終了
        break;
    }
}

仕組みとしては以下のとおりです。

  • 取得したい条件などをクエリパラメータを連想配列$paramsとして保存
  • twitteroauthでリクエスト
  • リクエストして帰ってくるJSONの中にnext_tokenが入っているので取得
  • next_tokenを連想配列にぶちこむ
  • forとかwhileで繰り返しリクエスト

Twitter側に迷惑のかからぬよう適宜for内でsleepしても良いと思います。ちゃんと取得できてます!
rapture_20211218004055.png

パラメータについて

パラメータや取得できる情報などはドキュメントから確認してください。特に開始時間・終了時間をクエリに直接ぶちこめるようになったのはありがたいです。時間を指定する場合、日本時間にしたいなら+09:00を末尾に追記。

特に**tweet.fieldの部分はとてもたくさんの情報を取得できるので必見です。**デフォルトではIDと本文しか帰ってきませんよ!詳しくは↓

(おまけ)従来のv1.1での100件以上取得コード

最後におまけ。従来のv1.1で取得したい場合のサンプルコードも載せときます。

v1_1.php
<?php
require_once "vendor/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;

loop_req("#hashtags -RT", 10);

function loop_req($keyword, $loop_count)
{
    // Set API Key and AccessToken here
    global $CK, $CS, $AT, $ATS;
    $connection = new TwitterOAuth($CK, $CS, $AT, $ATS);
    $params = [
        'q' => $keyword,
        'count' => 100
    ];
    for ($i = 0; $i < $loop_count; $i++) {
        $results = $connection->get("search/tweets", $params);
        foreach ($results->statuses as $val) {
            // Write the post-acquisition process here
            $tweet_results[] = $val->text;
        }

        //Conditional branching to see if there are more tweets that can be retrieved
        if (isset($results->search_metadata->next_results)) {
            // Get max_id
            $max_id = preg_replace('/.*?max_id=([\d]+)&.*/', '$1', $results->search_metadata->next_results);
            // Add max_id to params
            $options['max_id'] = $max_id;
        } else {
            break;
        }
    }
    return $tweet_results;
}

最後にお詫び…

アドカレの予定に登録していた記事案にて「日本語の情報が一つもないAPIを紹介」と書いていたのですが、TwitterAPIの記事に変更させていただきました…
本来、TikTokアカウントでログインできるようにするTikTok APIを解説する予定でしたが、TikTok API自体が今年の5月にリリースされたばかりであまりにも使いみちが無い…というわけで代打としてTwitter APIのPHP実装例に変更しました。

TikTok Login Kitを活用したログイン機能を実装したソースコードと解説を以下のリポジトリにアップロードしましたので、もしTikTok APIに興味がありましたら併せてご覧いただければ幸いです。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?