TwitterAPIを用いてツイートを取得できるよういろいろと試行錯誤してきましたが、またさらに少し改良しました。
前回までに作ったもの
①1度に取得できる最大の200件のツイートをTwitter APIを使って取得し、csvとして保存できるようにしてみた
(記事はこちら↓)

②タイムゾーンがUTC(イギリス)になっていたのをJST(日本)に変更した
(記事はこちら↓)

今回は200件以上取得することを目標にいろいろ調べてやってみたので記録しておきます。
目標
特定のアカウントのツイートを200件以上取得し、csvとして保存する。
やってみる
ぼんやり方針を考える
複数回APIを叩くのなら、繰り返し文が必要かな、というのはなんとなく考えてました。
2回目以降は直前に取得したツイートより1つ前のツイートから取得したいけれどどうすればよいのか・・・?
max_idというパラメータがあるらしい
調べると、パラメータとして「max_id」というのがあるようでした。
「max_id」で指定したIDを、取得してくるツイートの上限にすることができます。
なので、1回前に取得したツイートの中で一番小さいツイートIDから-1した数をmax_idに設定することで、続きからツイートを取得できるようになります。
max_id = int(<前回取得してきた中で一番古いツイートのID>) - 1
params["max_id"] = max_id
こんな感じで使ってmax_idを指定しました。
繰り返し処理
取得してくるツイートがなくなるまで、複数回APIを叩いて上限の200ツイートを取ってくるようにしたいので、繰り返し処理を書きました。
終了の条件は、200ツイート取得できたかどうかにしました。まだ続きがあればもう1回繰り返し、なければ終了。
#繰り返し処理
while True:
res = twitter.get(url, params=params)
~取得したリストの処理(省略)~
#繰り返し終了の条件
if len(<取得したツイートのリスト>) < params['count'] :
break
今書いてて気づきましたが、これでは全ツイート数が1回で取得するツイート数で割り切れるときにエラー吐きそうですね・・・。改善の余地あり・・。
まとめ コード全体
繰り返し処理とmax_idパラメータを駆使してなんとか複数回APIを叩く仕様にできました。
ただ、さかのぼれるツイート数の上限なのか期間の上限なのかわかりませんが、ツイートの量によっては全ツイート取得できず途中で止まっていることもあるような感じでした。
(私のツイートは400くらいしかなかったから全部とれますが・・!)
まだまだ改善の余地が大ありですが、いったんここで区切りとしたいと思います。
最後に今回作ったコードの全体を載せて記録しておきます。
中途半端な出来栄えではありますが、少しでもどなたかの参考になればうれしいです。
get_tweet.py ※別でアクセストークン等記載した.envファイルを作成
import os
import json
from requests_oauthlib import OAuth1Session
from dotenv import find_dotenv, load_dotenv
import pandas as pd
import datetime
from dateutil import tz
env_file = find_dotenv()
load_dotenv(env_file) # .envファイルを探して読み込む
# APIキーの設定
CONSUMER_KEY = os.environ.get('CONSUMER_KEY')
CONSUMER_SECRET = os.environ.get('CONSUMER_SECRET')
ACCESS_KEY = os.environ.get('ACCESS_KEY')
ACCESS_KEY_SECRET = os.environ.get('ACCESS_KEY_SECRET')
twitter = OAuth1Session(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_KEY, ACCESS_KEY_SECRET)
#エンドポイント
url = 'https://api.twitter.com/1.1/statuses/user_timeline.json'
# パラメータ設定(count:ツイート投稿数、screen_name:アカウント名)
params = {'count':200, 'screen_name':<アカウント名>}
#tweetを取得(1回目)
res = twitter.get(url, params=params)
#ステータスコードが正常値(200)のときの処理
if res.status_code == 200:
# json形式に変換
timelines = json.loads(res.text)
# 空のリスト型を作成
list_created_at_utc = []
list_created_at_jst = []
list_text = []
list_favorite_count = []
#データを作成したリストに追加
for data in timelines:
list_created_at_utc.append(datetime.datetime.strptime(data['created_at'], '%a %b %d %H:%M:%S %z %Y'))
list_text.append(data['text'])
list_favorite_count.append(data['favorite_count'])
#ここから2回目以降のツイート取得
if len(timelines) == params['count'] :
#パラメータにmax_idを追加
max_id = int(timelines[params["count"] - 1]["id"]) - 1
params["max_id"] = max_id
#ここから繰り返し処理
while True:
res = twitter.get(url, params=params)
timelines = json.loads(res.text)
for data in timelines:
list_created_at_utc.append(datetime.datetime.strptime(data['created_at'], '%a %b %d %H:%M:%S %z %Y'))
list_text.append(data['text'])
list_favorite_count.append(data['favorite_count'])
#終了の条件
if len(timelines) < params['count'] :
break
#max_idを更新
max_id = int(timelines[params["count"] - 1]["id"]) - 1
params["max_id"] = max_id
#イギリス時間を日本時間に変換
for utc in list_created_at_utc:
list_created_at_jst.append(utc.astimezone(tz.gettz('Asia/Tokyo')))
#DataFrame作成
df = pd.DataFrame({'time': list_created_at_jst,
'text': list_text,
'fav_count': list_favorite_count
})
#CSVに抽出
df.to_csv("tweets_" + params['screen_name'] + ".csv")
else:
print("ERROR: %d" % res.status_code)
