Xにおける特定のユーザーの投稿履歴をPythonからAPI経由で取得する(2024年1月時点)

検索しても出てくる情報が古くて難儀したので、現時点の情報を記載。
この記事はあくまで「素人のやっつけ仕事」を体験談として記載するもので、もっと良い記事を専門家が公開するまでのつなぎとして考えていただければと思います。

1.投稿履歴をAPI経由で取得するにはBasic以上のライセンスが必要
2.(有料化以前に対して)ライセンス認証形式が変更されている
3.(有料化以前に対して)取得できる情報が変更されている
4.取得制限100件の制約を前提にコードを組む必要がある
5.開発環境、開発者登録、アプリ認証キー取得
6.実際に使っているコード(3種類)
7.補足:さらにPythonで出来ること

1.投稿履歴をAPI経由で取得するにはBasic以上のライセンスが必要

2024年1月現在、XのAPIライセンスは以下の4通りです。
 Free:無料。
  
・1つのアプリ環境を構築できる。
  ・アプリ経由で自身の投稿を作成・削除できる。
  ・ユーザIDを指定すればプロフィール情報が取得ができる。
  ・アプリ経由の投稿作成・削除は1500件/月まで。
 Basic:$100/月
  
・2つのアプリ環境を構築できる。
  Freeの機能に加えて、
  ・過去7日間の投稿を検索し、取得できる。
  ・特定の投稿にリツイートやいいねしたユーザの一覧を取得できる。
  ・アプリ経由の投稿作成・削除は50,000件/月まで。
  ・投稿・リツイート・いいねの情報は1回100件/月間10,000件まで。
  Pro:$5,000/月
  
・3つのアプリ環境を構築できる。
  ・すべての投稿を検索し、取得できる。
  ・アプリ経由の投稿作成・削除は300,000件/月まで。
  ・投稿・リツイート・いいねの情報は1回100件/月間1,000,000件まで。
 Enterprise:$42,000/月~
  ・要商談

Freeでは投稿の取得ができないため、Basic以上のライセンスが必要です。
Basicも決して安いわけではないですが、Proに至っては個人で払うことが想定されてないかと思います。えっ?Enterprise?あれは見なかったことにましょう。
有料化以前はすぐに使えるEssential、審査が必要なElevatedなどがあったようですが、いずれにせよ現状の価格設定だとそもそも参入者が激減するわけですね。記事を書く人、読む人ともに無料時代とは段違いに少なくなっているはず。
そのため、趣味で$100/月を払って始めようとしても、ウェブ検索では無料化時代の記事ばかり引っかかるわけです。またProライセンスを使うような方はそもそも技術的蓄積があるので「初心者向け」解説を必要とせず、各種コミュニティなどで複雑な相談をやり取りしているかと思います。
従って「$100/月のBasicライセンス向け解説」というのは稀であり、私のような素人でも文章を残しておく価値はあるかと考えこの記事を用意しました。

2.(有料化以前に対して)ライセンス認証形式が変更されている

過去の無料ライセンス向け記事を読んで、データ取得リクエストをXのサーバに送るためのプログラミングコードを書きました。実行しました。
ほぼ確実にエラーメッセージが返ってきます。何故か。
ライセンス認証形式が変更されているため、そもそもXのサーバから「貴方の事なんか知りません」と言われます。
過去には「APIトークン」「API鍵」「接続トークン」「接続鍵」の組み合わせで認証していたようですが、現在は原則として「ベアラートークン」と呼ばれる認証鍵1本で認証を行います。また認証のために必要なコード群も変更されており、過去の記事およびサンプルコードは(少なくとも認証については)役に立ちません。
X開発者向けサイトにサンプルコードが転がってはいますが、解説はすべて英語かつ分かってる人向けのサイト構成なので完全な初心者だとキツイでしょう。

3.(有料化以前に対して)取得できる情報が変更されている

「認証のために必要なコード」が変更されたのはわかりました。
ベアラートークンが必要なので発行しました。
無料ライセンス向け解説記事を参考に、認証のために必要なコードだけ書き換えてデータ取得リクエストを送信しました!
やはりエラーメッセージが返ってきます。何故か。
無料ライセンス時代はXのアプリ上に表示されているあらゆる情報(いいねの数や表示された回数、添付された画像のURLなど)を取得できたようなのですが、この中に今は取得できない情報が含まれており、データ取得リクエストの中で取得できないはずの情報を明示的に要求するとエラーが返ってきます。
「どんなデータをどう要求すれば教えてくれるか、あるいは教えてくれないか」はやはり英文の開発者サイトにまとめられており、私はいちいち照合するのが途中でめんどくさくなったので基本的な情報だけ要求するようにしました。すなわち「ユーザID」「投稿ID」「投稿日時」「本文」です。
今回はなるべく素早くデータを取得しておきたい事情があり、習熟よりも取得開始を優先しました。反省。

4.取得制限100件の制約を前提にコードを組む必要がある

過去には何百件もまとめて取得できた時代もあったようですが、今はBasicでもProでも1リクエスト100件までしか取得できないです。ということは、100件を超えるデータを取得したい場合、何らかの手段で100件以下の単位に切り分けてリクエストを送信する必要があります。これはプログラミングとしては「配列の管理」「条件を変更しながらの繰り返し処理」で対応するのが王道なのですが、いずれも初心者が躓きがちな障害です。私も新しい言語に触れるたびによく躓きます。
今回はなるべく素早くデータを取(以下略)
あえてコードを「最新の100件を取得」「特定の日時以前を取得」「特定の日時以前を取得」に分けました。理由は後述します。

5.開発環境、開発者登録、アプリ認証キー取得

ごめんなさい。この項に関しては優秀なまとめ記事がいっぱいあるので解説を省略します。
・Pythonのインストール
 (Add python.exe to PATHはチェックしておきましょう)
・コマンドプロンプトでpip install requestsの実行
・コマンドプロンプトでpip install pandasの実行
 (Pythonにデフォルトで入ってた気がしますが念のため)
Twitter開発者ポータルで利用者登録
 (ライセンス購入の準備)
・Basicライセンスを購入
・アプリ使用目的などの設定
 (これからXのサーバにリクエストを送るための準備)
・認証キーの取得
 (Authentication Tokens でBearer TokenのGenerateボタンを押す)

6.実際に使っているコード(3種類)

あえて3つの機能に分けてます。 なおBasicライセンスで過去7日間までしか取得できないことを前提にしています。
使い方としてはメモ帳か何かに貼り付けて拡張子「py」で保存し、コマンドプロンプトで「python 実行したいコード.py」と入力することになります。
いずれも実行すると指定したファイル名のcsvファイルが実行ファイルと同じフォルダに保存されます。

1.最新の100件を取得 
 新しく「特定のユーザ」を対象にする際に使います。
 0件なら「keyError:Data」が返ってきます。
 取得したデータが100件未満ならこれで終わりです。
 100件を超えるようなら「一番古い投稿日時」をメモして2に進みます。

BEARER_TOKEN = "xxxxxx"
SEARCH_KEYWORD = "from:xxxxxx"
MAX_RESULTS = 100
import requests
URL = f"https://api.twitter.com/2/tweets/search/recent?query={SEARCH_KEYWORD}&tweet.fields=author_id,created_at&max_results={MAX_RESULTS}"
HEADERS = {"Authorization": f"Bearer {BEARER_TOKEN}"}
response = requests.request("GET", URL, headers=HEADERS).json()
import pandas
df = pandas.DataFrame(response['data'])
df.to_csv('xxxxxx.csv')

・BEARER_TOKEN に自分のベアラートークンを入力します。
・SEARCH_KEYWORDに「from:xxxxxx」の形でユーザ名を指定します。
 ユーザ名とはTwitterアカウントの@なんちゃら、の@より後方です。
・df.to_csv に保存するファイル名を指定します。
 毎回変えないと過去のcsvファイルを上書きしてしまいます。

2.特定の日時以前の100件を取得
 7日で100件を超える投稿をしているユーザを対象にする場合に使います。  取得したデータの中で「一番古い日時」を指定し、そこから100件を遡って取得します。このコードを繰り返すことで7日間の投稿すべてを取得することを目指します。(1か月の取得制限に引っかかるほど投稿が多いなら別の手を考える必要があります)

BEARER_TOKEN = "xxxxxx"
SEARCH_KEYWORD = "from:xxxxxx"
MAX_RESULTS = 100
import requests
URL = f"https://api.twitter.com/2/tweets/search/recent?query={SEARCH_KEYWORD}&tweet.fields=author_id,created_at&end_time=YYYY-MM-DDThh:mm:ss.000Z&max_results={MAX_RESULTS}"
HEADERS = {"Authorization": f"Bearer {BEARER_TOKEN}"}
response = requests.request("GET", URL, headers=HEADERS).json()
import pandas
df = pandas.DataFrame(response['data'])
df.to_csv('xxxxxx.csv')

・BEARER_TOKEN に自分のベアラートークンを入力します。
・SEARCH_KEYWORDに「from:xxxxxx」の形でユーザ名を指定します。
 ユーザ名とはTwitterアカウントの@なんちゃら、の@より後方です。
・URL の「YYYY-MM-DDThh:mm:ss.000Z」を指定日時に書き換えます。
 2024年1月2日午後3時15分なら「2024-01-02-T15:15:00.000Z」です。
 取得した投稿データもこの書式で記述されているのでコピペが楽です。
・df.to_csv に保存するファイル名を指定します。
 毎回変えないと過去のcsvファイルを上書きしてしまいます。


3.特定の日時以後の100件を取得
 
 過去に取得した投稿データと重複がないようにしたい場合に使います。
 合理的に動けるなら毎週同じ曜日の同じ時刻にデータ取得リクエストを送ればこの機能は要らないはずなのですが、そうもいかないこともあります。  例えば「前回の取得からまだ3日なのにデータを取得したくなった」「前回は日曜日だったけど今週は予定があるので土曜日と月曜日に取得したい」とかですね。1日の投稿が100件以下のユーザが対象ならば、この機能を毎日実行することで用が足ります。

BEARER_TOKEN = "xxxxxx"
SEARCH_KEYWORD = "from:xxxxxx"
MAX_RESULTS = 100
import requests
URL = f"https://api.twitter.com/2/tweets/search/recent?query={SEARCH_KEYWORD}&tweet.fields=author_id,created_at&start_time=YYYY-MM-DDThh:mm:ss.000Z&max_results={MAX_RESULTS}"
HEADERS = {"Authorization": f"Bearer {BEARER_TOKEN}"}
response = requests.request("GET", URL, headers=HEADERS).json()
import pandas
df = pandas.DataFrame(response['data'])
df.to_csv('xxxxxx.csv')

※前項の「end_time」を「start_time」に置き換えただけです。
・BEARER_TOKEN に自分のベアラートークンを入力します。
・SEARCH_KEYWORDに「from:xxxxxx」の形でユーザ名を指定します。
 ユーザ名とはTwitterアカウントの@なんちゃら、の@より後方です。
・URL の「YYYY-MM-DDThh:mm:ss.000Z」を指定日時に書き換えます。
 2024年1月2日午後3時15分なら「2024-01-02-T15:15:00.000Z」です。
 取得した投稿データもこの書式で記述されているのでコピペが楽です。
・df.to_csv に保存するファイル名を指定します。
 毎回変えないと過去のcsvファイルを上書きしてしまいます。

7.補足:さらにPythonで出来ること

最初に記述しましたが、プログラミングの王道としては「配列の管理」「繰り返し処理」というやり方があります。
これは何かというと、例えば…上記で日時をコピペして別のコードを起動する、ということを手作業で行っていますが、これは自動化できます。
また「特定のユーザ」をリストで用意して、順次実行ということも可能です。CSVのファイル名だって上書きしないように毎回何らかのルールで変更することが可能ですし、配列をきっちり管理できれば1枚のCSVにまとめて保存することもできます。
繰り返しになりますが、この記事はあくまで「素人のやっつけ仕事」を体験談として記載するもので、もっと良い記事を専門家が公開するまでのつなぎとして考えていただければと思います。

2024年6月24日追記
 上記の
 ・「特定のユーザ」をリストで用意して順次実行
 ・1つのファイルにまとめて保存
に加えて「定期的に実行」という工程をGoogleAppsScriptとGoogleスプレッドシートで自動化しました。
 Googleアカウントがあれば無料で実行できますので良かったらお試しください。


この記事が気に入ったらサポートをしてみませんか?