カーソルページングで Serenity の投稿とリプライをエクスポートする方法

著者:TwexAPI チーム
JA
他の言語:
日本語
English中文
TwexAPI
Serenity
カーソルページング
データエクスポート
投稿とリプライ

TwexAPI のカーソルページング API で Serenity(@aleabitoreddit)の公開投稿とリプライを保存します。checkpoint、重複排除、保存設計も扱います。

Quick Answer

Serenity のアクスポートをリトライや再起動、長期アーカイブに対応させるには、TwexAPI の POST /twitter/tweets-replies/page を使います。初回は screen_name: "aleabitoreddit" を送り、has_next_page が true の間は前回の next_cursor を渡します。1 ページあたり最大 20 件の公開投稿またはリプライを取得できます。当ページを保存して tweet_id で重複排除したあと、next_cursor をチェックミイントとして保存してください。

FAQ

通常の posts-replies ではなく paginated endpoint を使うべき場面は?

quick preview や small first export では通常 endpoint で十分です。resumable archive、scheduled job、network failure 後に再開したい dataset では paginated endpoint を使います。

checkpoint には何を保存すべきですか?

page の保存が成功した後に返った next_cursor を保存します。次回は同じ screen_name と cursor で再開します。current page を保存する前に cursor を保存すると、crash 時に data を skip する可能性があります。

繰り返し export で重複を避けるには?

database や analysis table では tweet_id を unique key にします。同じ post が再度出た場合は interaction counts など mutable fields を update し、新規 row は作りません。

Serenity の最新投稿を数件見るだけなら、ページングなしの取得で十分です。ページ単位のエクスポートが必要になるのは、公開投稿とリプライをローカルに保存し、失敗後に再開できるアーカイブを作りたい場合です。

この記事では、Serenity は公開 X アカウント @aleabitoreddit を指します。

TwexAPI の Get All Tweets and Replies by User by Page は、1 回のリクエストで最大 20 件の公開項目を返し、has_next_page と next_cursor を含みます。重要なのは cursor を保存することです。ページ処理に成功するたびに next_cursor を記録すれば、失敗時に最初からやり直さず、最後の checkpoint から再開できます。

ページングを使う場面

Answer: ページングを使う場面とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

カーソルページングは、単なるプレビューではなく再現可能なデータセットが必要なときに使います。たとえば、Serenity の公開投稿を毎日保存する、後でリプライ分析を行うためのデータを作る、前回実行後に増えた投稿だけ取得する、といった用途です。

最初はローカル JSON への書き出しで十分です。本番ジョブでは、ページごとに保存し、tweet_id で重複排除し、最後に成功した cursor を checkpoint テーブルまたはファイルに残してください。

API エンドポイント

Answer: API エンドポイントは本ガイドの TwexAPI エンドポイントを Bearer で呼び出して実装します。バッチ/ページングで約 5 Credits/回・20+ QPS です。

POST https://api.twexapi.io/twitter/tweets-replies/page

Authorization: Bearer <your_token>
Content-Type: application/json

最初のリクエストは screen_name のみです。続きは直前のレスポンスにある next_cursor を渡します。has_next_page が false になった場合、または cursor が返らなくなった場合は停止します。

curl --request POST \
  --url https://api.twexapi.io/twitter/tweets-replies/page \
  --header 'Authorization: Bearer <your_token>' \
  --header 'Content-Type: application/json' \
  --data '{"screen_name":"aleabitoreddit"}'

Python カーソルループ

Answer: Python カーソルループとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

次の例は、各ページを JSONL に追記し、次の cursor を checkpoint ファイルに保存します。すべてをメモリに集めて最後に 1 ファイルへ書くより、長いエクスポートで安全です。

1import json
2import os
3from pathlib import Path
4
5import requests
6
7TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
8URL = "https://api.twexapi.io/twitter/tweets-replies/page"
9SCREEN_NAME = "aleabitoreddit"
10HEADERS = {"Authorization": f"Bearer {TOKEN}"}
11OUTPUT = Path("serenity-tweets-pages.jsonl")
12CHECKPOINT = Path("serenity-checkpoint.json")
13
14def load_cursor():
15    if not CHECKPOINT.exists():
16        return None
17    return json.loads(CHECKPOINT.read_text(encoding="utf-8")).get("next_cursor")
18
19def save_cursor(cursor):
20    CHECKPOINT.write_text(
21        json.dumps(
22            {"screen_name": SCREEN_NAME, "next_cursor": cursor},
23            ensure_ascii=False,
24            indent=2,
25        ),
26        encoding="utf-8",
27    )
28
29def append_items(items):
30    with OUTPUT.open("a", encoding="utf-8") as output:
31        for item in items:
32            output.write(json.dumps(item, ensure_ascii=False) + "\n")
33
34cursor = load_cursor()
35page_count = 0
36item_count = 0
37
38while True:
39    body = {"screen_name": SCREEN_NAME}
40    if cursor:
41        body["next_cursor"] = cursor
42
43    response = requests.post(URL, headers=HEADERS, json=body, timeout=30)
44    response.raise_for_status()
45    payload = response.json()
46
47    items = [item for item in payload.get("data", []) if item]
48    append_items(items)
49    page_count += 1
50    item_count += len(items)
51
52    next_cursor = payload.get("next_cursor")
53    if not payload.get("has_next_page") or not next_cursor:
54        if CHECKPOINT.exists():
55            CHECKPOINT.unlink()
56        break
57
58    save_cursor(next_cursor)
59    cursor = next_cursor
60
61print(f"{page_count} ページを処理し、{item_count} 件を追記しました")

本番運用の注意点

Answer: 本番運用の注意点とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

  • 現在のページを保存できた後に next_cursor を保存します。ページ保存前に cursor だけ進めないでください。
  • データベースや分析テーブルへ保存する前に tweet_id で重複排除します。
  • created_at_datetime、cashtags、言語フィールド、エンゲージメント数を保存します。
  • 元の JSON レスポンスも短期間保管しておくと、後でフィールドマッピングを変更したときに再処理できます。
  • 削除済みまたは取得不能な投稿は、公開データアーカイブ上の通常の欠落として扱います。

関連リソース

Answer: 関連リソースとは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

免責事項

Answer: 免責事項とは、この事例で api.twexapi.io の TwexAPI Bearer API を使う手順です。通常の読み取りは 5 Credits(約 $0.05/1K)、対象プランは 20+ QPS です。2026-08-20 時点の公式 Post/User read は $5/$10 per 1K で、rate limit は endpoint ごとに異なります。

本記事は公開 X データの保存とアーカイブ方法を説明するもので、投資助言ではありません。取得した投稿、リプライ、cashtag、エンゲージメント指標だけを投資判断の根拠にしないでください。

カーソルページングで Serenity の投稿とリプライをエクスポートする方法