TwexAPI で Philippot の X データを収集する方法
公開 X アカウントから確認しやすいデータセットを作るなら、まずアカウント単位で整理します。プロフィールのスナップショットを保存し、公開タイムラインをページングし、必要なときだけ検索で範囲を絞ります。
この記事では f_philippot を screen name の例として使います。公開アカウントの handle は変わることがあるため、実行前に現在の screen name を確認してください。
収集プラン
このワークフローでは、主に 3 つの TwexAPI エンドポイントを使います。
| タスク | エンドポイント | 使う場面 |
|---|---|---|
| 公開プロフィールを取得 | GET /twitter/{screen_name}/about | 投稿を集める前に、アカウント情報を記録します。 |
| 投稿をページング取得 | POST /twitter/{screen_name}/timeline/page | cursor を使って最近のタイムライン投稿を集めます。 |
| 公開 X 結果を検索 | POST /twitter/advanced_search/page | トピック、語句、検索演算子で絞り込むときに使います。 |
生のレスポンスと正規化した行データは両方保存します。後で解析ルールを変えたとき、生の JSON が監査用の根拠になります。
アカウント情報を取得する
curl --request GET \
--url https://api.twexapi.io/twitter/f_philippot/about \
--header 'Authorization: Bearer <token>'プロフィールのスナップショットは投稿テーブルとは別に保存します。アカウント ID、表示名、プロフィール文、API が返す公開カウントなどを確認できます。
タイムライン投稿をページングする
POST /twitter/{screen_name}/timeline/page は count と next_cursor を受け取ります。1 ページ目では next_cursor を省略します。has_next_page が true の場合、返された next_cursor を次のリクエストに渡します。
curl --request POST \
--url https://api.twexapi.io/twitter/f_philippot/timeline/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"count": 20
}'レスポンスには現在ページの data とページング用フィールドが含まれます。
{
"code": 200,
"msg": "success",
"data": [],
"has_next_page": true,
"next_cursor": "DAAHCgAB...",
"requested_count": 20,
"effective_count": 20,
"parsed_count": 20
}Python コレクター
次のコレクターは、指定したページ数だけタイムラインを取得し、確認・重複排除・エクスポートに使いやすい行データへ整えます。
1import os
2from typing import Any
3
4import requests
5
6TOKEN = os.environ["TWEXAPI_BEARER_TOKEN"]
7SCREEN_NAME = "f_philippot"
8BASE_URL = "https://api.twexapi.io"
9
10def headers() -> dict[str, str]:
11 return {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
12
13def get_profile(screen_name: str) -> dict[str, Any] | None:
14 response = requests.get(
15 f"{BASE_URL}/twitter/{screen_name}/about",
16 headers=headers(),
17 timeout=30,
18 )
19 response.raise_for_status()
20 return response.json().get("data")
21
22def get_timeline_page(
23 screen_name: str,
24 *,
25 count: int = 20,
26 next_cursor: str | None = None,
27) -> dict[str, Any]:
28 payload: dict[str, Any] = {"count": count}
29 if next_cursor:
30 payload["next_cursor"] = next_cursor
31
32 response = requests.post(
33 f"{BASE_URL}/twitter/{screen_name}/timeline/page",
34 headers=headers(),
35 json=payload,
36 timeout=30,
37 )
38 response.raise_for_status()
39 return response.json()
40
41def normalize_post(post: dict[str, Any]) -> dict[str, Any]:
42 tweet_id = post.get("tweet_id") or post.get("id")
43 return {
44 "tweet_id": tweet_id,
45 "created_at": post.get("created_at_datetime") or post.get("created_at"),
46 "text": post.get("full_text") or post.get("text") or "",
47 "favorite_count": post.get("favorite_count") or 0,
48 "retweet_count": post.get("retweet_count") or 0,
49 "reply_count": post.get("reply_count") or 0,
50 "quote_count": post.get("quote_count") or 0,
51 "url": f"https://x.com/i/status/{tweet_id}",
52 }
53
54def collect_timeline(screen_name: str, max_pages: int = 3) -> list[dict[str, Any]]:
55 rows: list[dict[str, Any]] = []
56 cursor = None
57
58 for _ in range(max_pages):
59 page = get_timeline_page(screen_name, count=20, next_cursor=cursor)
60 rows.extend(normalize_post(post) for post in page.get("data", []))
61
62 if not page.get("has_next_page"):
63 break
64 cursor = page.get("next_cursor")
65 if not cursor:
66 break
67
68 return rows
69
70if __name__ == "__main__":
71 profile = get_profile(SCREEN_NAME)
72 posts = collect_timeline(SCREEN_NAME, max_pages=2)
73 print(profile.get("screen_name") if profile else SCREEN_NAME, len(posts))必要に応じてトピック検索する
このアカウントの投稿を集めるだけなら、タイムラインのページングを使います。トピックで絞ったサブセットが必要な場合だけ、advanced search by page を使います。
curl --request POST \
--url https://api.twexapi.io/twitter/advanced_search/page \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"searchTerms": ["from:f_philippot énergie"],
"sortBy": "Latest"
}'検索 query は各結果行と一緒に保存します。query がないと、その投稿がなぜデータセットに入ったのかを後で説明しづらくなります。
データ管理の注意点
- 各実行の
screen_name、実行時刻、エンドポイント、query、cursor を記録します。 tweet_idを重複排除の主キーにします。- フィールドを整える前に、生の JSON を保存します。
- エンゲージメント数を、内容の正確性や重要性の証明として扱わないようにします。
- レポートで引用する前に、引用投稿、メディア、返信の文脈を人が確認します。
まとめ
f_philippot のような公開アカウントでは、プロフィール情報を保存し、タイムラインをページングし、必要なときだけトピック検索を加えるのが実用的です。
これにより、API レスポンスに含まれない性能主張、感情スコア、分析結論を足さずに、再利用しやすい収集手順を提示できます。