WEIR

ツイートを CSV 出力:ユーザーの全ポストを一括取得【2026】

ツイートを CSV 出力して一括保存する方法。自分のポストは X のアーカイブで、公開アカウントは年ごとの検索で 2006 年までさかのぼります。pip 不要の Python 付き。


公開 · 更新 · 約 7 分で読めます · Read in English · 阅读中文版

カバー画像:2006 年まで全部 CSV に

ツイートを CSV に出力して一括保存するには、自分なら X のアーカイブ、他の公開アカウントなら年ごとの検索を使います。

X(旧 Twitter)のあるアカウントの全ポスト(ツイート)を表にしたい、研究者やマーケター、開発者向けです。アーカイブの手順、pip 不要の Python スクリプト、実際の費用をまとめました。例の API は私たちが運営する Weir なので、その前提で読んでください。

1 年分のポストを取得する例です。

curl --request POST \
  --url https://api.weirapp.io/v1/x/search \
  --header "Authorization: Bearer $WEIR_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"fromUsers":["jack"],"since":"2006-01-01T00:00:00Z","until":"2007-01-01T00:00:00Z","limit":20}'
  1. 誰のツイートか確認自分のならアーカイブが一番です。
  2. キーを取得登録して、キーを WEIR_API_KEY に入れます。
  3. 1 年分を検索fromUsers と since、until を指定します。
  4. 最後までページ送りmeta.nextCursor を null まで送り返します。
  5. 全年を CSV に出力1 ファイル、1 ポスト 1 行です。

ステップ 1:自分のツイートは X のアーカイブで一括保存する

自分のツイートなら、API は要りません。X がアカウント全体のアーカイブを無料で作ります。

X のヘルプセンターの手順です。

  1. **[設定とプライバシー]から[アカウント]**を開きます。
  2. 自分の X データの項目(英語版の Your X data)を選び、コードで本人確認をします。
  3. データを申請します。 準備に数日かかることがあると X は書いています。
  4. ZIP をダウンロードします。X からメールかプッシュ通知が届きます。

ZIP の中身は HTML と JSON のファイルで、CSV は入っていません。開き方は Twitter アーカイブの開き方(英語)にあります。

表にしたいなら、無料の Twitter アーカイブビューア(英語)に ZIP を入れると、アップロードせずに CSV で保存できます。

アーカイブは、ログイン中の自分のアカウントにしか使えません。他のアカウントは次のステップからです。

ステップ 2:API キーを取得して 1 年分を検索する

カードなしで 登録(英語)し、API keys でキーを作って環境変数に入れます。

export WEIR_API_KEY="weir_live_..."

Weir の検索は、アカウントを fromUsers、期間を since と until で受け取ります。since はその時刻を含み、until は含みません。

まず、呼び出しを 1 つの関数にまとめます。標準ライブラリだけなので、pip は要りません。

import csv, json, os, sys, time, urllib.error, urllib.request

API = "https://api.weirapp.io/v1/x/search"
HEADERS = {"Authorization": "Bearer " + os.environ["WEIR_API_KEY"],
           "Content-Type": "application/json"}

def search(body):
    req = urllib.request.Request(API, json.dumps(body).encode(), HEADERS)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.load(r), r.headers["x-credits-charged"]

検索は X の最初の日々まで届きます。10 月 26 日に、X の共同創業者 @jack を until 2006 年 3 月 22 日、limit: 3 で検索しました。2 ページ目に、20 番のポストがありました。

{
  "id": "20",
  "text": "just setting up my twttr",
  "url": "https://x.com/jack/status/20",
  "createdAt": "2006-03-21T20:50:14.000Z",
  "author": { "username": "jack", "followersCount": 12546666 },
  "likeCount": 309561,
  "retweetCount": 124562
}

X で最初の公開ポストが、今日のポストと同じ形で返ってきます。

id は文字列のまま扱います。今の ID は大きすぎて、浮動小数点数では正確に表せません。

ステップ 3:カーソルで 1 年分を最後まで取得する

X が 1 回で返すのは約 20 件です。応答の meta.nextCursor をそのまま送り返すと、次のページが返ります。

止める合図は null だけです。

def year_of_posts(user, year, max_pages=200):
    body = {"fromUsers": [user], "limit": 20, "since": f"{year}-01-01T00:00:00Z",
            "until": f"{year + 1}-01-01T00:00:00Z"}
    for _ in range(max_pages):
        try:
            page, _ = search(body)
        except urllib.error.HTTPError as e:
            if e.code != 429:  # 402 はクレジット切れ:止める
                raise
            time.sleep(int(e.headers.get("Retry-After", "5")))
            continue
        yield from page["data"]
        body["cursor"] = page["meta"]["nextCursor"]
        if not body["cursor"]:
            return

@jack の検索も、いつもと同じ形で終わりました。20 番のあとの呼び出しは空でした。

{ "data": [], "meta": { "nextCursor": null } }

最後の呼び出しは 1 クレジットで、3 回で 4 ポスト、合計 7 クレジットでした。

ステップ 4:ユーザーの全ツイートを 1 つの CSV に出力する

新しい年から順に回し、1 ポストを 1 行に書きます。python all_tweets.py JAXA_jp のように実行します。

FIELDS = ["id", "createdAt", "text", "likeCount", "retweetCount",
          "replyCount", "viewCount", "url"]
user = sys.argv[1]

with open(f"{user}.csv", "w", newline="", encoding="utf-8-sig") as file:
    writer = csv.DictWriter(file, fieldnames=FIELDS, extrasaction="ignore")
    writer.writeheader()
    for year in range(2026, 2005, -1):  # X の最初の年、2006 年まで
        for post in year_of_posts(user, year):
            writer.writerow(post)
        file.flush()  # 途中で止まっても、終わった年は残る

ステップ 2 の関数、ステップ 3、ステップ 4 を順に 1 つのファイルに並べれば、スクリプトの完成です。

  • utf-8-sig:BOM 付きの UTF-8 で、Excel で開いても日本語が文字化けしません。
  • アカウントがなかった年:空で返り、1 クレジットずつかかります。
  • 返信を除く:body に "onlyOriginal": True を足します。

検索はリポストも返します。リポストの行は likeCount が 0 で、元の数は retweetedPost にあります。除くなら body に "query": "-filter:nativeretweets" を足します。ほかの条件は X の検索コマンド一覧 にあります。

X API でユーザーの全ツイートを取得できる?

できますが、タイムラインからではありません。X のドキュメントによると、ユーザーのポストのタイムラインは最新 3,200 件までです。古いスクリプトが 3,200 件で止まるのは、この上限のためです。

X の全期間検索に、この上限はありません。2006 年 3 月までさかのぼり、1 回 500 件まで返します。

全期間検索は従量課金のアカウントで使えます。2026 年 10 月時点で 1 ポスト $0.005 なので、3,200 ポストで $16 です。

公式 API の Tweepy のコードは、Python でツイートを取得する方法 にあります。

3,200 ツイートを一括取得するといくら?

Weir の検索は 1 回 1 クレジットに、ポスト 1 件ごとに 1 クレジットです。20 件のページなら 21 クレジットです。

1 アカウントの 3,200 ポストを取得
公式 X API$16
Weir、$5 パック約 $0.68
TwitterAPI.io約 $0.48

3,200 ポストは 160 ページで、年ごとに最後の呼び出しが 1 回ずつ加わります。合わせて約 3,400 クレジットです。

毎月の無料 5,000 クレジットに収まるので、最初の 1 アカウントは無料です。大きな作業は X API コスト計算ツール(英語)で試算できます。

時間も考えておきます。

2120 件のページ 1 回のクレジット
15無料枠で 1 分に送れる検索
12 分無料枠で 3,200 ポストを取得する時間

無料枠は 1 分 30 リクエストで、検索は 2 回分に数えます。上限に当たると、スクリプトの 429 の分岐が待ちます。

うまく動かないときは

  • 402 で止まった:クレジット切れで、再試行しても通りません。翌月の無料枠を待つか、パックを買います。
  • 2 ページ目で 400:body が変わっています。その年をカーソルなしでやり直します。
  • 途中で止まった:CSV の最後の id を ツイート ID を日時に変換するツール(英語)で調べ、その年から再開します。
  • Excel で ID が 2.0E+18 になる:表示だけの問題です。id 列を文字列として読み込みます。

鍵アカウントは取得できません。検索にも出てきません。

X の利用規約は、書面の許可がないスクレイピングを認めていません。Weir は公開データを読むだけで、投稿はできません。自分の用途が規約に合うかは自分で判断してください。これは法的な助言ではありません。

Weir が向かないケース

  • 自分のアカウント:アーカイブは無料で完全です。DM も入っています。
  • 量だけが目的:TwitterAPI.io は 1,000 ツイート $0.15 で、Weir の有料単価より安く、投稿もできます。
  • X との契約が必要:公式 API の全期間検索を使います。
  • 手で数件見るだけ:日付で過去のポストを検索する方法 なら無料です。

よくある質問

ユーザーの全ツイートを無料で取得できますか?

自分のアカウントなら、X の設定からアーカイブを申請すれば無料です。公開アカウントなら、Weir の毎月の無料 5,000 クレジットで約 4,700 ポスト取得できます。公式 X API に、ポストを読む無料プランはありません。

他人のツイートを CSV に出力できますか?

公開アカウントならできます。fromUsers で 1 年ずつ検索し、各年を最後までページ送りします。鍵アカウントは承認されたフォロワーにしか見えないので、どの API でも取得できません。

ツイート取得が 3,200 件で止まるのはなぜですか?

ユーザーのタイムラインを読んでいるからです。X のドキュメントは、タイムラインを最新 3,200 件までとしています。日付の範囲で検索すれば、@jack の 2006 年 3 月の最初のポストまで届きました。

Python でツイートを CSV に出力するには?

csv.DictWriter に extrasaction="ignore" と encoding="utf-8-sig" を使います。1 ポストを 1 行に書き、年ごとに flush します。ステップ 4 のスクリプトがそのとおりです。

参考資料

X のヘルプセンターと利用規約は 2026 年 10 月 21 日に、ほかは 10 月 26 日に確認しました。