在浏览器中,X 呈现的仍然是一条直观的动态时间线。但在数据接口层面,公开数据的规范与约束要严格得多:用户名不等同于帖子 URL,引用推文(Quote)不同于转推(Retweet),回复(Reply)也不等同于引用推文;当遇到已删除或受保护的帖子时,系统应当清晰报错,而不是返回一条空记录。
本教程将基于 SocQ X API 搭建一套生产级采集工作流,深入讲解官方 API 与公开数据访问的区别、端点路由选择、输入参数规范化、异步任务处理、返回字段解析、数据刷新周期以及合规与负责任使用建议。
核心摘要: 将用户名、
x.com或twitter.com的帖子链接或搜索关键词发送至POST /v1/x/{resource},保存返回的任务 ID 并轮询/v1/tasks/{id}。在数据库设计时,如果没有设置专门的资源类型区分字段,切勿将引用推文、转推和回复混存入同一张数据表。
官方 X API 还是公开数据 API?
官方 X API 采用按权限划分的付费模式。如果你需要执行发帖、发送私信(DM)、管理广告、以特定用户身份关注或点赞,或是接入流式传输(Streaming)等需要账号授权的操作,官方 API 是唯一合规的选择。鉴于其准入门槛与定价经常变动,涉及写操作与合作方案请始终以官方最新开发者文档为准。
SocQ 则是一个面向公开数据的读取服务层,支持采集公开用户资料、指定帖子、用户历史推文窗口、关键词搜索、社交互动关系及热门趋势。SocQ 无需使用 X 用户身份进行授权,也不提供官方的发帖或广告管理功能。如需了解定价与供应商对比,可参阅 Twitter API 替代方案、Twitter 爬虫与抓取 API 评测 以及 TwitterAPI.io 替代方案。在选择具体接口前,建议先明确业务所需的数据访问模式。
选对 X 数据接口端点
| 资源类型 | 端点 | 支持的公开输入格式 | 典型应用场景 |
|---|---|---|---|
| 用户资料 (Profiles) | /v1/x/profiles | 用户名(支持带或不带 @) | 获取公开账号信息与可见互动统计数据 |
| 单条帖子 (Posts) | /v1/x/posts | x.com 或 twitter.com 的帖子状态 URL | 采集指定帖子的详细内容 |
| 用户发帖 (User Posts) | /v1/x/user-posts | 用户名 | 采集指定账号最近发布的公开推文 |
| 关键词搜索 (Search) | /v1/x/search | 搜索关键词 / 表达式 | 发现最新(Latest)或最热门(Top)的公开推文 |
| 帖子回复 (Replies) | /v1/x/post-replies | 帖子状态 URL | 采集指定帖子的评论与回复内容 |
| 引用推文 (Quotes) | /v1/x/post-quotes | 帖子状态 URL | 采集引用了指定帖子的二次创作推文 |
此外还支持以下接口:
post-retweeters:传入公开帖子 URL,获取转推用户列表。followers-list与following-list:传入用户名,支持通过results_limit指定返回数量(200 至 2000,步长为 200)。trends:传入数字格式的 WOEID(地理位置代号),获取指定区域热门趋势。
需要特别说明的是:引用推文、转推和回复属于完全不同的数据资源。引用推文自带独立的推文正文;转推者列表返回的是一组用户资料;回复则是挂载在特定会话链下的帖子。在进行数据库写入(upsert)时,切勿将它们当作相同对象混为一谈。
规范化处理用户名、URL 和关键词
在接收并处理外部输入时,建议在持久化原始输入的同时清洗并生成一份标准化副本:
- 兼容
@前缀:统一接收带或不带@的用户名,并在存储时去除@保存为标准的格式。 - 兼容域名格式:同时支持
x.com与twitter.com域名。对于帖子类接口,URL 必须包含数字格式的/status/{id}路径。 - 剔除跟踪参数:清理掉 URL 中的 utm、s 等跟踪查询参数;只要状态 ID 完整,无需强求特定的移动端或区域域名。
- 针对性去重:用户名去重时不区分大小写,帖子去重则严格依据状态 ID(Status ID)。
- 入参预校验:在提交 API 请求前,校验并拒绝空的关键词或空用户名。
- 保留检索上下文:在元数据或溯源记录中完整保留提交的搜索表达式,以便后续数据分析时能准确溯源每条推文入库的原因。
参数限制方面:user-posts 与 search 端点的 results_limit 支持 20 到 2000(步长为 20);搜索排序参数 sort_by 支持 latest(最新)或 top(热门);post-replies 另外还支持按 relevance(相关度)、latest(最新)或 likes(点赞数)进行排序。
提交采集任务
获取公开用户资料:
curl -X POST "https://api.socq.ai/v1/x/profiles" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"usernames":["openai","@github"]}'
采集单条指定帖子(同时支持 x.com 和 twitter.com):
curl -X POST "https://api.socq.ai/v1/x/posts" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls":["https://x.com/X/status/2073395918011789670"]}'
采集指定用户的近期发帖窗口:
curl -X POST "https://api.socq.ai/v1/x/user-posts" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"usernames":["openai","github"],"results_limit":40}'
根据关键词检索公开推文:
curl -X POST "https://api.socq.ai/v1/x/search" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query":"AI lang:en","results_limit":100,"sort_by":"latest"}'
将推文回复与引用推文作为独立任务分别采集:
curl -X POST "https://api.socq.ai/v1/x/post-replies" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls":["https://x.com/X/status/2073395918011789670"],"results_limit":20,"sort_by":"latest"}'
curl -X POST "https://api.socq.ai/v1/x/post-quotes" \
-H "Authorization: Bearer $SOCQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls":["https://x.com/X/status/2073395918011789670"],"results_limit":20}'
提交请求后,请妥善保存接口返回的 task_id,并将其与对应的资源类型及规范化输入参数一并记录入库。
轮询任务状态,避免重复提交
SocQ 采用异步任务处理模式。提交任务后,需轮询任务接口获取执行结果:
curl "https://api.socq.ai/v1/tasks/$TASK_ID?limit=100" \
-H "Authorization: Bearer $SOCQ_API_KEY"
任务状态为 queued(排队中)或 running(进行中)均属正常状态。轮询时建议采用指数退避(Exponential Backoff)策略,避免高频请求。当状态变为 succeeded 时,读取 data.results.items 数组;若 has_more 为 true,则携带返回的 next_cursor 继续分页获取后续数据。
一个健壮的后台 Worker 应该对以下数据进行持久化记录:
- 业务批次 ID 与 SocQ 任务 ID(
task_id)。 - 请求的资源类型以及规范化后的用户名、URL 或查询词。
- 任务提交时间与完成时间。
- 终态状态码及错误分类归因。
- 上次已处理的结果游标(
cursor)。
务必注意:Worker 进程异常重启绝不应当成为重新向 API 提交相同采集任务的理由,应优先检查未完成任务的 ID 并恢复轮询。
理解返回数据字段
所有资源对象均包含一组通用的基础字段:id、platform、resource、type、url、created_at、collected_at 以及扩展信息 extra。
- 用户资料(Profiles):包含
username、name、description(个人简介)、avatar_url、cover_url、is_verified(认证状态)、is_private(是否私密账号)以及各项公开可见的互动计数。受保护账号不在公开数据采集范围内。 - 帖子推文(Posts):包含
text(正文)、language、author、互动统计指标;公开状态下还包含media(图片/视频等多媒体)、hashtags(标签)和mentions(提及用户)。建议以平台的数字id作为实体主键,而将帖子状态 URL 留存为溯源字段。 - 回复与引用:数据结构复用帖子结构;转推者列表则复用用户资料结构;热搜趋势属于区域维度的榜单数据,并非独立的推文实体。
遇到已删除推文或私密账号时,采集任务应在输入验证或任务执行阶段明确返回失败状态。千万不要插入一条伪造的空帖子记录,也不要虚构全为 0 的互动指标,更不要错误地将采集时间 collected_at 代替为帖子的发布时间 created_at。
搜索结果本质上是经算法排序后的实时快照。latest(最新)和 top(热门)分别代表同一受限时间窗口内的两种不同排序视图,并不构成完整的历史全量推文档案。
Python 采集 Worker 示例
以下为采集资料、单帖和搜索的完整 Python 示例代码:
import time
import requests
BASE = "https://api.socq.ai/v1"
HEADERS = {
"Authorization": f"Bearer {SOCQ_API_KEY}",
"Content-Type": "application/json",
}
def collect(resource, payload):
created = requests.post(
f"{BASE}/x/{resource}",
headers=HEADERS,
json=payload,
timeout=30,
)
created.raise_for_status()
task_id = created.json()["data"]["task_id"]
delay = 2
while True:
response = requests.get(
f"{BASE}/tasks/{task_id}",
headers=HEADERS,
timeout=30,
)
response.raise_for_status()
task = response.json()["data"]
if task["status"] == "succeeded":
return task["results"]["items"]
if task["status"] in {"failed", "cancelled"}:
raise RuntimeError(task)
time.sleep(delay)
delay = min(delay * 1.5, 15)
# 采集指定账号资料
profiles = collect("profiles", {"usernames": ["openai"]})
# 关键词搜索
hits = collect("search", {
"query": "AI lang:en",
"results_limit": 40,
"sort_by": "latest",
})
在正式投入生产环境前,请务必补充游标分页(Cursor Pagination)、超时重试限制、针对偶发 5xx 响应的有界重试机制,以及入库时的幂等性更新(Idempotent Upsert)。
将推文实体与指标快照分离建模
在实际业务场景中,推文本体的基础信息与推文的动态互动指标变化频率截然不同,建议拆分为实体表与快照表进行建模:
x_entity (推文静态实体表)
resource
platform_id
canonical_url_or_username
text_or_description
author_id
created_at
first_seen_at
last_seen_at
x_snapshot (推文动态指标快照表)
resource
platform_id
collected_at
likes_count
replies_count
reposts_count
quotes_count
source_task_id
入库时建议以 resource + id 作为复合主键进行 upsert 更新。如果将引用、回复和原帖存放于同一张帖子表中,前提必须是 resource 字段作为必填区分列。转推者名单则建议存放在独立的用户资料表或关系边表中。
切勿通过转推者快照推算引用推文的增长趋势,这两种维度的指标在业务语义上无法直接替换。
入库前的校验规则
在将采集到的数据写入业务数据库前,建议执行以下完整性校验:
platform字段值必须为x。resource必须与请求的具体端点类型严格匹配。- 对于帖子形态的资源,状态 URL 中必须包含合法的数字
/status/ID。 - 当采集端点为
user-posts且包含作者信息时,推文作者用户名应与最初提交的目标账号一致。 - 各项互动计数字段必须为非负整数或 null。
- 时间戳字符串必须能够被标准日期解析器正确解析。
- 因账号私密或推文已被删除导致的采集失败,绝不能在清洗流程中被转换成一条看似成功的空推文。
对于未通过校验的异常数据,应将其连同原始任务的 Payload 一同归档至隔离区(Dead Letter Queue),便于排查问题。
各类实体的推荐刷新频率
不同类型的实体,数据变动周期差异很大,建议参考以下调度周期:
| 实体类型 | 推荐初始采集周期 | 设定依据 |
|---|---|---|
| 用户资料 (Profiles) | 每周或每月一次 | 账号简介、头像等基本信息变化频率较低 |
| 指定帖子 (Known Posts) | 活跃期每小时至每天一次 | 新发帖的公开互动指标在前期变动剧烈 |
| 用户发帖窗口 (User Posts) | 监控场景每小时至每天一次 | 个人时间线属于有界且按时间排序的流 |
| 关键词搜索 (Search) | 根据关键词热度灵活调度 | latest 与 top 均为实时流,并非全量历史库 |
| 回复与引用 (Replies / Quotes) | 帖子发布初期的活跃阶段每小时一次 | 社交互动与会话关系往往呈突发式集中涌现 |
| 关注与粉丝列表 (Followers / Following) | 每周一次 | 关系网络体量庞大,且分页步长较大(200 起) |
| 热门趋势 (Trends) | 每小时一次或每日数次 | 各地区 WOEID 榜单随时间定期轮换 |
如果下游业务分析并不需要更高精度的时效性快照,应适当调低采集频率,避免资源浪费。
常见问题与排错指南
提交帖子 URL 后没有返回数据?
请首先确认该帖子 URL 是否为公开可见状态、目前是否仍可正常访问,且 URL 中是否包含合法的数字 /status/{id}。若帖子已被作者删除或账号已设为受保护状态,采集任务会干净利落地报错失败,此时应记录并保留输入阶段的错误日志。
搜索结果似乎不够完整?
接口中的 results_limit 参数仅代表当前请求返回的数量上限。X 平台的搜索排序算法、索引延迟以及选择 latest(最新)或 top(热门)排序都会导致返回的内容有所不同。建议在保存推文数据的同时,连同检索词和所选排序方式一同记录。
引用推文为什么被存成了转推?
二者不仅调用的 API 端点不同,返回的数据结构也有本质区别。务必在数据库的复合主键中保留 resource 字段,以确保能够正确区分两者。
粉丝/关注接口为什么报错拒绝了 limit 参数?
followers-list 和 following-list 接口仅接受 200 至 2000 的数值,且步长必须为 200。而用户发帖(user-posts)和关键词搜索(search)接口的步长则为 20。
采集到的互动指标与网页浏览器看到的不一致?
公开采集的互动数据属于特定时间点抓取的离线快照,而前端展示的数据可能存在缓存延迟、平台数字取整或防刷限流等情况。在判定接口解析出错之前,请优先核对数据的抓取时间戳 collected_at。
为什么同一位用户出现了两条重复记录?
建议先对用户名进行大小写归一化清洗,并在入库主键中优先使用全局唯一的公开用户 ID。当遇到账号修改用户名(Screen Name)的情况时,建议在数据库中维护一张历史别名映射表。
负责任地使用 X 平台公开数据
在采集和使用公开数据时,建议始终遵循最小必要原则,仅收集与业务正当目的直接相关的公开字段。严禁通过技术手段绕过受保护账号、用户拉黑、登录墙或其他平台访问控制措施。应避免针对个人进行敏感画像分析,切勿在缺乏适当保护措施的情况下,将数据用于对个人权益产生重大影响的自动化决策中。
X 平台上的公开数据可能包含个人信息。在开展数据处理前,应根据所在国家或地区的合规要求明确合法合规依据,制定健全的数据留存与销毁策略,严格保护 API 密钥和导出的数据文件,并定期同具备资质的法务团队核对 X 平台最新的服务条款。需要注意的是,公开数据 API 仅提供数据访问能力,并不代表赋予了对推文文本或多媒体内容的无限制再授权与分发许可。
常见问题 (FAQ)
采集 X / Twitter 上的公开数据是否合法?
这在全球范围内并没有绝对通用的标准结论,主要取决于所在的司法管辖区、采集的数据类型、使用的采集手段、实际使用目的、平台服务协议以及所采取的隐私保护措施。本文内容仅作为工程技术交流,不构成任何专业法律意见。
SocQ API 能否完全替代官方 X API?
不能完全替代。若业务涉及发推发帖、发送私信、投发广告、流式监听等需要用户账号身份授权的写操作,仍必须接入官方 X API。SocQ 专注于为合规场景提供稳定、高效的公开数据读取支持。
能否采集私密账号或已删除的推文?
不能。针对私密账号或已删除内容,接口设计上会直接返回明确的错误,无法也不会去强行绕过平台的访问控制。
引用推文(Quotes)和转推(Retweets)是一回事吗?
不是一回事。引用推文带有发布者自己的独立文字和二次创作内容,属于帖子(Posts)类型;而转推者列表获取的是参与转发的用户资料(Profiles)集合;回复(Replies)则是属于会话树的另一独立资源。
搜索接口能否拉取到全量历史推文?
不能。搜索接口返回的是在特定关键词查询下、由平台算法索引的一个有界、有序的推文窗口,并不等同于推特自建站以来的全量历史冷数据库。
数据入库去重时推荐使用什么主键?
首选推荐使用 resource + id 的复合主键。若遇到极端情况下公开数字 ID 缺失,可退而使用经过规范化处理的状态 URL 或标准用户名作为兜底键。
立即测试您的 X 数据采集工作流
只需提交公开的用户名或帖子链接,即可通过标准化的接口与完整的溯源上下文,轻松获取高质量的 X 平台结构化数据。