WEIR

Python でツイートを取得する 3 つの方法【2026 年】

ツイートを Python で取得する 3 つの方法を比較。X API の料金、Tweepy と twscrape の現状、pip 不要のコード、日本語ポストの検索と文字化けしない CSV 保存まで。


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

カバー画像:標準ライブラリだけでツイート取得

Python でツイートを取得する方法は、X の公式 API、スクレイピング用ライブラリ、REST API の 3 つです。

この記事は、X(旧 Twitter)のポスト(ツイート)をスクリプトや CSV で扱いたい開発者向けです。それぞれの費用と壊れやすさを比べ、3 つ目の方法で動くコードを示します。例に使う API は、私たちが運営する Weir です。

キーを WEIR_API_KEY に入れて実行すると、日本語のポストが返ります。標準ライブラリだけなので、pip は要りません。

import json, os, urllib.request

body = {"query": "Python", "language": "ja", "limit": 20}
req = urllib.request.Request(
    "https://api.weirapp.io/v1/x/search", json.dumps(body).encode(),
    {"Authorization": "Bearer " + os.environ["WEIR_API_KEY"],
     "Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=60) as r:
    for post in json.load(r)["data"]:
        print(post["author"]["username"], post["text"][:60])
  1. キーを取得登録して、キーを WEIR_API_KEY に入れます。
  2. ポストを検索POST /v1/x/search に条件を送ります。
  3. 1 アカウントを取得GET /v1/x/users/{user}/posts を呼びます。
  4. カーソルで次へmeta.nextCursor を null になるまで送り返します。
  5. CSV に保存1 ポストを 1 行に書きます。

2026 年に Python でツイートを取得する 3 つの方法

2026 年 10 月時点の比較です。

方法 必要なもの 読み取りの費用 主なリスク
公式 X API 開発者アカウント 1 ポスト $0.005 量が増えると高い
twscrape、twikit 自分の X アカウント 無料 予告なく壊れる
Weir REST API API キー 1,000 ポストで 1,050 クレジット X ではない第三者

X API を Python から使う(Tweepy)

X の API は従量課金です。クレジットを先に買い、ポストを 1 件読むごとに $0.005 かかります。料金ページによると、読めるのは月 300 万ポストまでです。

同じポストを UTC の同じ日に 2 回読んでも、課金は原則 1 回です。

最近の検索は直近 7 日分を 1 回 100 件まで返します。全期間検索は 2006 年 3 月までさかのぼり、1 回 500 件まで返します。

Tweepy は定番の Python クライアントで、最新は 4.17.0 です。

import os, tweepy

client = tweepy.Client(bearer_token=os.environ["X_BEARER_TOKEN"])
response = client.search_recent_tweets(
    query="Python lang:ja -is:retweet",
    max_results=100,
    tweet_fields=["created_at", "public_metrics"],
)
for tweet in response.data or []:
    print(tweet.id, tweet.public_metrics["like_count"])

X 自身も Python SDK の xdk を公開しています。

100 件のリクエストは 50 セントなので、1 万ポストで $50 です。代わりに X 自身の規約、書き込みの権限、1 回 500 件の全期間検索が手に入ります。

日本語の Tweepy 解説には、API が無料だった頃の記事が多く残っています。今の料金は X API の料金 にまとめました。

スクレイピング用ライブラリ:twscrape、twikit、snscrape

これらは x.com の Web アプリが内部で使うエンドポイントを呼びます。2026 年 10 月 25 日の状況です。

  • snscrape:最後のリリースは 2023 年 6 月で、issue #996「All Twitter scrapes are failing」は開いたままです。
  • twikit:最新は 2025 年 2 月の 2.3.3 です。2026 年 4 月からの KeyError も未解決です。
  • twscrape:最新は 0.20.1 と更新は続いていますが、README には認証済みの X アカウントが必要とあります。

X が内部を変えると、メンテナーが追いつくまで動きません。リスクはあなたのアカウントが負います。

X の利用規約も、書面による許可のないスクレイピングを認めていません。これは法的な助言ではありません。

ステップ 1:API キーを取得して設定する

無料で登録(英語)すると、カードなしで API キーを作れます。キーは環境変数に入れます。

export WEIR_API_KEY="weir_live_..."

Windows の PowerShell なら $env:WEIR_API_KEY = "weir_live_..." です。呼び出しは 1 つの関数にまとめます。

import json, os, time, urllib.error, urllib.parse, urllib.request

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

def call(path, body=None, **params):
    url = API + path + ("?" + urllib.parse.urlencode(params) if params else "")
    data = None if body is None else json.dumps(body).encode()
    req = urllib.request.Request(url, data, HEADERS)  # data があれば POST
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.load(r), r.headers["x-credits-charged"]

ステップ 2:Python でツイートを検索する

検索は POST /v1/x/search に JSON を送ります。query に X の検索構文を書くか、fromUsers などの項目を使えば Weir が変換します。

page, credits = call("/v1/x/search", {
    "query": "Python",
    "fromUsers": ["Qiita", "zenn_dev", "gihyojp"],
    "language": "ja",
    "onlyOriginal": True,  # 返信を除く
    "since": "2026-08-01T00:00:00Z",
    "limit": 20,
})
for post in page["data"]:
    print(post["createdAt"][:10], post["likeCount"], post["id"])
print("credits:", credits)

10 月 25 日に limit: 3 で実行すると、3 件で 4 クレジットでした。1 件を抜粋します。

{
  "id": "2112786983210869229",
  "text": "🔐 ピックアップ ✨\n\nPyarmorによるPythonコードの難読化を…",
  "lang": "ja",
  "createdAt": "2026-10-21T06:04:05.000Z",
  "author": { "username": "zenn_dev" },
  "likeCount": 6,
  "viewCount": 1597
}

id は大きすぎて浮動小数点数では正確に表せないので、文字列のまま扱います。カウントの null はゼロではなく、X が値を返さなかったという意味です。

「Pythonコード」のように日本語と続いた語も拾えています。query の書き方は X の検索窓と同じで、公式 API の v2 とは一部違います。対応は X の検索コマンド一覧 にまとめました。

ステップ 3:1 つのアカウントのツイートを取得する

タイムラインは GET /v1/x/users/{user}/posts です。{user} はユーザー名か数字の ID で、limit は 20 までです。

page, credits = call("/v1/x/users/zenn_dev/posts", limit=20)
timeline = page["data"]

ポストとリポストが新しい順に返り、固定ポストが先頭に来ます。10 月 25 日に試すと、Zenn 公式の 9 月 8 日の固定ポストが最初でした。

{
  "id": "2097226800359510493",
  "text": "🎉 第5回 Agentic AI Hackathon with Google Cloud 開催中 …",
  "createdAt": "2026-09-08T07:33:28.000Z",
  "likeCount": 30
}

limit: 3 で 6 クレジットでした。最初のページだけ、アカウントを特定するプロフィール 1 件分の 2 クレジットが加わります。

返信は /v1/x/users/{user}/replies です。存在しないか公開されていないアカウントは 404 になります。

ステップ 4:カーソルで次のページを取得する

一覧には meta.nextCursor が付きます。そのまま送り返すと次のページが返り、止める合図は null だけです。検索はカーソルを body に、GET はクエリ文字列に入れます。

def search_pages(body, max_pages=10):
    cursor = None
    for _ in range(max_pages):
        payload = {**body, "cursor": cursor} if cursor else body
        try:
            page, _ = call("/v1/x/search", payload)
        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"]
        cursor = page["meta"]["nextCursor"]
        if not cursor:
            return
  • ページ数の上限:広い検索でも、ページ送りと課金が止まります。
  • 429 と 402 の違い:429 は待てば通り、402(英語)はクレジットの追加が必要です。
  • 同じ body:カーソルは元の条件と結び付いていて、変えると 400 になります。

limit を大きくしても、X が 1 ページで返すのは 20 件ほどです。

ステップ 5:ツイートを CSV に保存する

extrasaction="ignore" を付けると、指定した列だけが残ります。

import csv

FIELDS = ["id", "createdAt", "username", "text", "likeCount", "viewCount", "url"]
query = {"query": "Python", "language": "ja", "minLikes": 50, "onlyOriginal": True}

with open("posts.csv", "w", newline="", encoding="utf-8-sig") as file:
    writer = csv.DictWriter(file, fieldnames=FIELDS, extrasaction="ignore")
    writer.writeheader()
    for post in search_pages(query, max_pages=5):
        writer.writerow({**post, "username": post["author"]["username"]})

utf-8-sig はファイルの先頭に BOM を付けます。Microsoft のサポートページによると、BOM 付きなら UTF-8 の CSV を Excel でそのまま開けます。日本語も文字化けしません。

Excel は長い ID を指数表記で見せますが、CSV には全桁が残っています。

1 万件のツイートを取得するといくら?

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

1 万ポストを読む費用
公式 X API$50
Weir、$5 パック約 $2.10

500 ページで 10,500 クレジットです。$5 のパックは 25,000 クレジットで、期限はありません。

無料の 5,000 クレジットなら、約 4,760 ポスト読めます。試算は X API コスト計算ツール(英語)でできます。

うまく動かないときは

  • KeyError: 'WEIR_API_KEY':環境変数がありません。実行するターミナルで設定します。
  • HTTP Error 401:キーが間違っているか、無効です。
  • HTTP Error 429:速すぎます。無料枠は 1 分 30 リクエストで、検索は 2 回分に数えます。

Weir が向かないケース

  • 投稿や代理の操作:書き込めるのは X の公式 API だけです。
  • X との直接契約:一次データが必須なら、公式 API です。
  • 1 回 500 件の全期間検索:1 回の件数は X のほうが多いです。
  • 量だけが目的:もっと安い第三者もあり、Twitter API の代替(英語)で比べられます。

よくある質問

Python で無料でツイートを取得できますか?

一部はできます。X の公式 API に無料プランはなく、スクレイピング用ライブラリは無料でもよく壊れます。Weir は毎月 5,000 クレジットが無料で、約 4,760 ポスト分です。ほかの選択肢は $0 でポストを読む方法 で比べています。

Tweepy は 2026 年も使えますか?

使えます。最新の 4.17.0 は X API v2 に対応しています。ただし 1 ポスト $0.005 の料金と、クレジットのある開発者アカウントの Bearer Token が必要です。

snscrape が動かないのはなぜですか?

2023 年 6 月から、Twitter の取得が「blocked (404)」で失敗しています。issue #996 は開いたままで、リリースもそれ以来ありません。

参考資料

いずれも 2026 年 10 月 25 日に確認しました。