用 SocQ 把 Twitter/X 社区名称、简介、规则、成员与版主数量整理成资料表,连同来源和采集时间一起保存。再连接社区帖子,你的研究资料就有明确的社区背景与规则可供复核。
SocQ X Community API 按公开社区 URL 查询资料。本教程展示请求与结果字段,并将资料导出为带来源和采集时间的 JSON、CSV。
快速答案: 将
x.com/i/communities/{数字ID}链接放入urls,提交到POST /v1/x/community。任务成功后,从data.results.items读取社区名称、简介、规则、成员与版主数量,以及加入和邀请政策。帖子使用独立的 Community Posts 接口查询。
从社区链接建立资料表
将目标社区链接放入 urls,即可查询该社区的名称、简介、规则、成员与版主数量,以及加入和邀请政策。以下以 Build in Public 的社区链接为例:
https://x.com/i/communities/1493446837214187523
链接末尾的数字是社区 ID。将包含 /i/communities/{数字ID} 的完整社区链接放入 urls。
从名称开始整理资料时,先找到对应社区 URL。用数字社区 ID 匹配记录,分别保存名称相同但 ID 不同的社区。
| 需要回答的问题 | 使用接口 |
|---|---|
| 这个社区有哪些资料可读取? | X Community |
| 能从这个社区采集哪些帖子? | X Community Posts |
| 某条讨论中的帖子如何相互回复? | X Thread Context |
本接口查询主题社区资料。Community Notes 是附在帖子上的注释,属于独立数据类型。
请求社区详情
设置 SOCQ_API_KEY 后提交社区 URL:
curl -X POST "https://api.socq.ai/v1/x/community" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls":["https://x.com/i/communities/1493446837214187523"]}'
批量查询时,在 urls 数组中加入其他公开社区链接。每条返回记录对应一个社区;数量按实际返回记录统计。
将 data.task_id 保存到 TASK_ID,读取已有任务:
curl "https://api.socq.ai/v1/tasks/$TASK_ID?limit=100" \
-H "Authorization: Bearer $SOCQ_API_KEY"
queued、running 或 retrying 时,间隔检查。任务成功后读取 data.results.items,以及其他已保存结果页;失败时查看 data.error_message。结果翻页读取的是已保存数据,不会刷新社区资料。
读取规则、数量和加入政策
下面展示社区资料的字段示例,省略部分字段,并节选一条规则:
{
"id": "1493446837214187523",
"type": "community",
"name": "Build in Public",
"metrics": {"members_count": 268858, "moderators_count": 6},
"join_policy": "Open",
"invites_policy": "MemberInvitesAllowed",
"rules": [
{
"id": "1493447542045958144",
"name": "Share what you're working on",
"description": "Don't be scared to share unfinished work"
}
],
"collected_at": "2026-10-15T08:12:58.252843Z"
}
text 保存简介,rules 保存结构化规则,metrics 保存数量。规则名称和描述分别保存;来源未提供的描述保留 null。
metrics.members_count 记录成员总数,metrics.moderators_count 记录版主总数。与采集时间一起保存后,可用于比较同一社区在不同采集时间的数量变化。
join_policy 和 invites_policy 分别保存加入与邀请政策的原始字符串。为已知值添加显示标签时,保留原值;遇到新值时直接显示原文。实际加入权限需在 X 的当前产品界面核验。
用 Python 导出社区资料表
将以下只使用标准库的任务函数保存为 socq_collect.py:
import json
import os
import time
from urllib.parse import urlencode
from urllib.request import Request, urlopen
BASE = "https://api.socq.ai/v1"
PENDING = {"queued", "running", "retrying"}
def api(method, path, payload=None):
body = json.dumps(payload).encode("utf-8") if payload is not None else None
request = Request(
BASE + path, data=body, method=method,
headers={
"Authorization": "Bearer " + os.environ["SOCQ_API_KEY"],
"Content-Type": "application/json",
},
)
with urlopen(request, timeout=60) as response:
result = json.load(response)
if result.get("code") != 200:
raise RuntimeError(result)
return result["data"]
def collect(endpoint, payload):
task_id = api("POST", "/" + endpoint, payload)["task_id"]
print("Task:", task_id, flush=True)
path = "/tasks/" + task_id
deadline = time.monotonic() + 600
data = api("GET", path + "?limit=100")
while data["status"] in PENDING:
if time.monotonic() >= deadline:
raise TimeoutError("Resume GET " + path + "; do not resubmit automatically")
time.sleep(2)
data = api("GET", path + "?limit=100")
if data["status"] != "succeeded":
raise RuntimeError(data.get("error_message") or data["status"])
items, seen_cursors = [], set()
while True:
if time.monotonic() >= deadline:
raise TimeoutError("Resume pagination for " + task_id)
page = data["results"]
items.extend(page["items"])
if not page["has_more"]:
return task_id, items
cursor = page.get("next_cursor")
if not cursor or cursor in seen_cursors:
raise RuntimeError("Missing or repeated result cursor")
seen_cursors.add(cursor)
data = api("GET", path + "?" + urlencode({"limit": 100, "cursor": cursor}))
if data["status"] != "succeeded":
raise RuntimeError("Task is not ready for result pagination")
在同一目录保存 export_communities.py:
import csv
import json
from socq_collect import collect
urls = ["https://x.com/i/communities/1493446837214187523"]
task_id, items = collect("x/community", {"urls": urls})
with open("communities.json", "w", encoding="utf-8") as f:
json.dump({"task_id": task_id, "input": {"urls": urls}, "items": items},
f, ensure_ascii=False, indent=2)
fields = ["community_id", "url", "name", "description", "members_count",
"moderators_count", "join_policy", "invites_policy", "rules_json", "collected_at"]
def csv_cell(value):
if value is None:
return ""
if isinstance(value, str) and value.lstrip().startswith(("=", "+", "-", "@")):
return "'" + value
return value
with open("communities.csv", "w", encoding="utf-8-sig", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fields)
writer.writeheader()
for item in items:
metrics = item.get("metrics") or {}
row = {"community_id": item.get("id"), "url": item.get("url"),
"name": item.get("name"), "description": item.get("text"),
"members_count": metrics.get("members_count"),
"moderators_count": metrics.get("moderators_count"),
"join_policy": item.get("join_policy"),
"invites_policy": item.get("invites_policy"),
"rules_json": json.dumps(item.get("rules"), ensure_ascii=False),
"collected_at": item.get("collected_at")}
writer.writerow({k: csv_cell(v) for k, v in row.items()})
python3 export_communities.py
JSON 保留原始标准记录与输入链接。CSV 为每条返回社区提供一行审阅数据,规则列表以 JSON 序列化,避免逗号或换行破坏规则结构;rules_json 中的 null 与空数组仍可区分。CSV 为首个非空白字符是 =、+、- 或 @ 的文本加上单引号,标识列按文本导入。
某个输入没有返回资料时,将本次结果记为空,并单独保存查询时间。已保存的旧资料继续保留原采集时间,供历史对照。
把社区资料连接到帖子采集
需要讨论内容时,将同一个确认过的 URL 提交到 X Community Posts。这会创建独立任务,并采用自己的数量上限。社区帖子教程展示了如何在导出时保留每条帖子的输入社区来源。
为资料保存社区 ID、来源 URL、任务 ID 与采集时间。采集帖子时,为每条帖子附上输入社区,便于按社区 ID 连接资料表与帖子表。
将简介、规则与采集到的帖子放在一起复核,注明各自的采集时间。需要某条帖子的回复关系时,继续阅读线程上下文教程。
让社区资料成为可复用的研究基础
SocQ 将社区资料整理为标准字段,配合本文代码即可保存资料表与完整规则。按社区 ID 连接帖子采集后,简介、规则和讨论有了共同来源,便于你建立研究档案、核对样本和更新历史记录。
常见问题
Twitter 社区 API 返回什么?
返回社区名称、简介、规则、成员与版主数量、加入和邀请政策等字段。字段含义与计费说明见 X Community API 页面。
社区迁移后如何查询资料?
X 已发布 Communities 向 XChat 的迁移公告。查询资料时仍以目标社区 URL 为输入:任务成功后读取返回记录,空结果单独保存查询时间,任务失败时查看错误信息。实际加入和参与功能以 X 当前界面为准。
可以按名称搜索社区吗?
查询输入是社区 URL。先确认名称对应的链接,再将链接放入 urls。
成员数包含成员或管理员名单吗?
返回的是成员与版主的汇总数量。具体账号名单属于独立数据,不在这份资料响应中。
Open 政策表示现在一定可以加入吗?
Open 是资料中返回的加入政策。实际加入权限在 X 的当前界面核验;本接口用于读取资料。
会同时取得帖子或 Community Notes 吗?
社区帖子使用 X Community Posts 查询,Community Notes 是独立的帖子注释数据。本文接口返回社区资料。
可以按成员数给社区活跃度排名吗?
成员和版主数量用于描述规模。研究活跃度时,采集帖子后在应用中按 published_at 选定时间范围,再统计样本内的帖子数、作者数或互动计数。