Python でツイートを取得する 3 つの方法【2026 年】
ツイートを Python で取得する 3 つの方法を比較。X API の料金、Tweepy と twscrape の現状、pip 不要のコード、日本語ポストの検索と文字化けしない CSV 保存まで。
Tarun Khatri
公開 · 更新 · 約 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])
- キーを取得登録して、キーを WEIR_API_KEY に入れます。
- ポストを検索POST /v1/x/search に条件を送ります。
- 1 アカウントを取得GET /v1/x/users/{user}/posts を呼びます。
- カーソルで次へmeta.nextCursor を null になるまで送り返します。
- 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 クレジットです。
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 日に確認しました。
- X API pay-per-usage pricing(英語):https://docs.x.com/x-api/getting-started/pricing
- X API search introduction(英語):https://docs.x.com/x-api/posts/search/introduction
- X API search operators(英語):https://docs.x.com/x-api/posts/search/integrate/operators
- X Terms of Service(英語、10 月 9 日発効、Wayback の 10 月 17 日版):https://x.com/en/tos
- Tweepy on PyPI(英語):https://pypi.org/project/tweepy/
- xdk on PyPI(英語):https://pypi.org/project/xdk/
- snscrape on PyPI(英語):https://pypi.org/project/snscrape/
- snscrape issue #996(英語):https://github.com/JustAnotherArchivist/snscrape/issues/996
- twikit on PyPI(英語):https://pypi.org/project/twikit/
- twikit issue #425(英語):https://github.com/d60/twikit/issues/425
- twscrape on PyPI(英語):https://pypi.org/project/twscrape/
- twscrape README(英語):https://github.com/vladkens/twscrape
- Python codecs, utf-8-sig(英語):https://docs.python.org/3/library/codecs.html
- Opening CSV UTF-8 files correctly in Excel(英語):https://support.microsoft.com/en-us/office/opening-csv-utf-8-files-correctly-in-excel-8a935af5-3416-4edd-ba7e-3dfd2bc4a032
- Weir billing(英語):https://docs.weirapp.io/billing
- Weir pagination(英語):https://docs.weirapp.io/pagination
- Weir での実測(10 月 25 日)