如何用 TwexAPI 采集 Philippot 的 X 数据
如果你需要从公开 X 账号整理可复核的数据集,先从账号本身开始:保存账号资料快照,分页采集公开时间线,再在需要更窄范围时使用搜索。
本文使用 f_philippot 作为示例 screen name。公开账号可能更换 handle,运行前请先确认当前 screen name。
采集计划
这个流程主要用三个 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。第一页不传 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 与每条结果一起保存。否则之后很难解释某条帖子为什么进入数据集。
数据清洁
- 记录每次运行的
screen_name、采集时间、端点、query 和 cursor。 - 使用
tweet_id作为去重主键。 - 先保存原始 JSON,再做字段整理。
- 不要把互动数当作某个说法准确或重要的证明。
- 在报告引用前,人工复核引用帖、媒体内容和回复上下文。
小结
对于 f_philippot 这样的公开账号,实用流程是:保存账号资料、分页采集时间线帖子、按需运行话题搜索,并让数据集保留可审计记录。
这样读者拿到的是可复用的采集方法,而不是没有依据的性能宣传、情绪判断或分析结论。