Twitter APIへの再帰リクエストサンプル

3 min読了の目安(約3100字TECH技術記事

なぜ再帰リクエストが必要か

Twitter APIは、無料で使える範囲だと、30daysやfullarchiveのsandboxとなり、いちリクエストにつき、100ツイートしか取得できません(user_timelineは200)。そのため、リクエストで戻ってくる値にnextトークンがついてきます。それを元にもう一度リクエストすることで、前の続きから100件取得ということができる

どう実装するか

csvに保存する工程は抜かします

  1. APIにリクエスト投げる用のパラメータ定義
  2. リクエストを投げる
  3. 返ってきたオブジェクトを処理する
  4. nextトークンが返ってきたオブジェクトに入っていたらそれを含めて再度リクエストを投げる

4で再帰呼び出しを行う関数で、引数にnextトークンがあったら、それを含めてリクエストを飛ばすように定義していきます。

再帰関数を組む

def searchWordsRecurrent(from_date, to_date,res = None):
    url = "https://api.twitter.com/1.1/tweets/search/fullarchive/[Twitter AppのENV_NAME].json"
    keyword = "任意のキーワード"
    print('----------------------------------------------------')
    params = {'query' : keyword, 'maxResults' : 100,'fromDate':from_date,'toDate':to_date}

    #レスポンスが引数で与えられていたら
    if res is not None:
        params['next'] = res['next']
    result = twitter.get(url, params = params)

    #CSVのヘッダーを定義
    header = ['id','User Name','User ID','Follows','Followers','User Location','content','time']
    search_timeline = {}
    if result.status_code == 200:
         with open('sample.csv', 'w') as f:
             search_timeline = json.loads(result.text)
             writer = csv.writer(f)
             writer.writerow(header)
             for tweet in search_timeline['results']:
	         date = datetime.strptime(tweet['created_at'],'%a %b %d %H:%M:%S %z %Y')
                 tmp = []
                 tmp.append(tweet['id'])
                 tmp.append(tweet['user']['name'])
                 tmp.append(tweet['user']['screen_name'])
                 tmp.append(tweet['retweet_count'])
                 tmp.append(tweet['favorite_count'])
                 tmp.append(tweet['user']['location'])
                 tmp.append(tweet['text'])
		 tmp.append(f"{date.year}-{date.month}-{date.day} {date.hour}:{date.minute}:{date.second}")

                 writer.writerow(tmp)
                 tmp = []
             print(len(search_timeline['results']))
    else:
        print("ERROR: %d" % req.status_code)
    if 'next' in search_timeline:
        searchWordsRecurrent(from_date, to_date,search_timeline)

    return;

解説

Premium search full-archive-APIを用いて、特定キーワードを含むツイートのID、ツイート主(ID、フォロー数、フォロワー数、ロケーション)、ツイート文、ツイート日時を取得しています。
1リクエストごとに、何日から何日までと区別のつくCSV形式で保存するようにしています
Twitter APIは、maxResultsに入り切らなかったら、返答としてNEXTトークンを返してくれるので、それがあったら、NEXTトークンをリクエストに加えてあげると、続きからとって来れます。以下引用

公式の説明

Each Tweet data request contains a 'maxResults' parameter (range 10-500, with a default of 100. Sandbox environments have a maximum of 100) that specifies the maximum number of Tweets to return in the response. When the amount of data exceeds the 'maxResults' setting (and it usually will), the response will include a 'next' token and pagination will be required to receive all the data associated with your query (see the HERE section for more information).

https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search

Twitter APIから帰ってきているオブジェクト

https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/user-object

https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/tweet-object