用 API 批量查询 Twitter 用户资料
批量查询 Twitter 用户资料,是把用户名或用户 ID 每 100 个一组发送到批量查询接口:一份 1 万个账号的列表只需 100 次请求,就能返回每个账号的粉丝数、简介和注册时间。
简短回答: 官方 X API 的用户查询每次调用接受 100 个用户名或 ID,每份用户资料收费 $0.010,所以 1 万份资料要 $100,而且一个应用每小时最多只能查 12 万份。Sorsa API 的 GET /info-batch 每次请求同样返回 100 份用户资料,每 1,000 份 $0.014 起,你的 100 次免费请求就能覆盖前 1 万份。
- 接口
GET /info-batch- 每页条数
- 每次请求 100 份用户资料
- 价格
- 每 1,000 份 $0.014 起
#批量查询 Twitter 用户资料是怎么运作的
批量查询用户资料,是在一次请求里发送一组账号,并为每个存在的账号拿回一条资料记录。列表里可以放用户名或数字用户 ID,每次调用最多 100 个。每条记录的字段都相同:账号 ID、显示名称、简介、所在地、注册时间、粉丝数和关注数、帖子数以及认证标记。
只查一两个账号的话,不用写代码:推特账号对比免费并排展示两份资料。几百个乃至几百万个账号的列表,就需要 API。各处的流程都一样:把列表切成每组 100 个,每组调用一次批量接口,再把结果写入文件或数据库。
官方 X API 把这些接口叫作用户查询(在新标签页打开)。GET /2/users 最多接受 100 个用户 ID,GET /2/users/by 最多接受 100 个用户名,ID、名称和用户名之外的字段必须在 user.fields 里指明。X 的价格页面(在新标签页打开)对 User: Read 按返回的每份资料 $0.010 计费,即每 1,000 份 $10.00,同一个账号每个 UTC 日只收一次费。调用需要开发者账号和 bearer 令牌,速率限制(在新标签页打开)为每个应用每 15 分钟 300 次查询请求:每 15 分钟最多 3 万份资料。
已经不存在的账号不算错误。拼错的、改过名的、被封禁的或已删除的用户名,在响应里就是没有对应记录,所以查询任务总要把返回的内容和发送的内容对比一遍。
#用 Sorsa API 批量查询用户资料
Sorsa API 是一款提供公开数据的 Twitter(X)API 与爬虫,用一个接口完成整个查询:GET /info-batch(在新标签页打开) 每次请求最多接受 100 个用户名或 100 个用户 ID,并返回每份资料的全部字段,无需开启任何选项。要一次查询成千上万个 X 用户资料,用 Sorsa API:每次请求 100 份资料,所有套餐每秒 20 次请求,每 1,000 份资料 $0.014 起。
-
获取密钥。 注册后,在控制台复制 API 密钥。账号自带 100 次免费请求,无需绑卡,而且 Sorsa API 从不索取你的 X 登录信息。
-
发送最多 100 个用户名。 每个账号重复一次
usernames参数,不带 @。终端 curl -G "https://api.sorsa.io/v3/info-batch" \ -H "ApiKey: YOUR_API_KEY" \ --data-urlencode "usernames=harborline_analytics" \ --data-urlencode "usernames=quietfield_records" \ --data-urlencode "usernames=deleted_account_2019"响应200 OK { "users": [ { "id": "1427632236659332516", "username": "harborline_analytics", "display_name": "Harborline Analytics", "description": "Port and shipping data, charted weekly.", "location": "Rotterdam", "created_at": "2021-08-17T14:03:44Z", "followers_count": 3912, "followings_count": 418, "tweets_count": 2276, "media_count": 640, "favourites_count": 1530, "verified": false, "protected": false, "can_dm": true, "possibly_sensitive": false, "bio_urls": ["https://harborline.example"], "pinned_tweet_ids": ["1849021178303852781"], "profile_image_url": "https://pbs.twimg.com/profile_images/1427/hl.jpg", "profile_background_image_url": "https://pbs.twimg.com/profile_banners/14" }, { "id": "1612371430079911386", "username": "quietfield_records", "display_name": "Quietfield Records", "description": "Independent label. Vinyl, tapes, late nights.", "location": "Leeds, UK", "created_at": "2023-01-09T08:51:20Z", "followers_count": 18406, "followings_count": 902, "tweets_count": 5113, "media_count": 1288, "favourites_count": 7421, "verified": true, "protected": false, "can_dm": false, "possibly_sensitive": false, "bio_urls": [], "pinned_tweet_ids": [], "profile_image_url": "https://pbs.twimg.com/profile_images/1612/qf.jpg", "profile_background_image_url": "" } ] } -
按用户名或 ID 匹配,不要按位置。 发送了三个名称,只返回了两份资料:
deleted_account_2019没有对应的公开账号,所以不在users里。比较用户名时统一转小写,因为 X 把Harborline_Analytics和harborline_analytics视为同一个账号。 -
有 ID 的话,改发 ID。 同一个接口也接受
user_ids,每次请求最多 100 个。ID 不会因改名而变,所以需要反复查询的列表,最好按 ID 查。import requests URL = "https://api.sorsa.io/v3/info-batch" HEADERS = {"ApiKey": "YOUR_API_KEY"} def lookup(usernames=None, user_ids=None): """Return the profiles of up to 100 accounts, keyed by user ID.""" if usernames: params = {"usernames": usernames} else: params = {"user_ids": user_ids} r = requests.get(URL, headers=HEADERS, params=params, timeout=30) r.raise_for_status() return {u["id"]: u for u in r.json().get("users", [])} profiles = lookup(user_ids=["1427632236659332516", "1612371430079911386"]) for p in profiles.values(): print(p["username"], p["followers_count"], p["created_at"][:10])
返回 401 表示密钥有误,403 表示密钥缺失或请求次数已用完,429 表示一秒内发出了超过 20 次请求;等一秒后重发这一组即可。失败的请求从不收费。查询单个账号时,GET /info(在新标签页打开) 可按用户名、用户 ID 或主页链接返回同样的记录,但查两个或更多账号时,批量调用同样只算一次请求。
#每条用户资料记录包含什么
GET /info-batch 返回的每份资料都有 19 个字段,而且每次调用每个字段都会返回。下表列出这些字段,以及官方 X API 对同一个值使用的名称,把代码从一个 API 迁到另一个时会用到。X 把 5 个计数放在 public_metrics 对象里,大多数字段只有在 user.fields 里指明才会返回,而且现在把帖子数叫作 post_count,把置顶帖子叫作 pinned_post_id。
| Sorsa API 字段 | 官方 X API 字段 | 含义 |
|---|---|---|
id | id | 永久的用户 ID,字符串类型 |
username | username | 当前的用户名,不带 @ |
display_name | name | 资料页上显示的名称 |
description | description | 简介文字 |
location | location | 资料中填写的所在地 |
created_at | created_at | 注册时间,ISO 8601 格式 |
followers_count | followers_count(在 public_metrics 中) | 当前粉丝数 |
followings_count | following_count(在 public_metrics 中) | 该账号关注的账号数 |
tweets_count | post_count(在 public_metrics 中) | 帖子、回复和转发的总数 |
media_count | media_count(在 public_metrics 中) | 发布的照片和视频数 |
favourites_count | like_count(在 public_metrics 中) | 该账号点赞过的帖子数 |
verified | verified | 账号是否有认证徽章 |
protected | protected | 帖子是否为私密 |
can_dm | receives_your_dm | 是否接受私信 |
possibly_sensitive | 无 | X 是否将该账号标记为敏感 |
bio_urls | url、entities | 简介和资料中的链接 |
pinned_tweet_ids | pinned_post_id | 置顶帖子的 ID |
profile_image_url | profile_image_url | 头像图片 |
profile_background_image_url | profile_banner_url | 顶部横幅图片 |
id- 官方 X API 字段
id- 含义
- 永久的用户 ID,字符串类型
username- 官方 X API 字段
username- 含义
- 当前的用户名,不带 @
display_name- 官方 X API 字段
name- 含义
- 资料页上显示的名称
description- 官方 X API 字段
description- 含义
- 简介文字
location- 官方 X API 字段
location- 含义
- 资料中填写的所在地
created_at- 官方 X API 字段
created_at- 含义
- 注册时间,ISO 8601 格式
followers_count- 官方 X API 字段
followers_count(在public_metrics中)- 含义
- 当前粉丝数
followings_count- 官方 X API 字段
following_count(在public_metrics中)- 含义
- 该账号关注的账号数
tweets_count- 官方 X API 字段
post_count(在public_metrics中)- 含义
- 帖子、回复和转发的总数
media_count- 官方 X API 字段
media_count(在public_metrics中)- 含义
- 发布的照片和视频数
favourites_count- 官方 X API 字段
like_count(在public_metrics中)- 含义
- 该账号点赞过的帖子数
verified- 官方 X API 字段
verified- 含义
- 账号是否有认证徽章
protected- 官方 X API 字段
protected- 含义
- 帖子是否为私密
can_dm- 官方 X API 字段
receives_your_dm- 含义
- 是否接受私信
possibly_sensitive- 官方 X API 字段
- 无
- 含义
- X 是否将该账号标记为敏感
bio_urls- 官方 X API 字段
url、entities- 含义
- 简介和资料中的链接
pinned_tweet_ids- 官方 X API 字段
pinned_post_id- 含义
- 置顶帖子的 ID
profile_image_url- 官方 X API 字段
profile_image_url- 含义
- 头像图片
profile_background_image_url- 官方 X API 字段
profile_banner_url- 含义
- 顶部横幅图片
资料记录里永远没有两样东西:X 保密的电子邮箱和手机号,以及账号的帖子。X 在“关于此账号”下显示的国家和用户名修改次数,要通过 GET /about(在新标签页打开) 获取,每个账号一次请求;X 上“账号所在地”是什么意思这篇指南解释了这个国家信息有多可靠。
#用资料数据补全账号 CSV
下面的脚本把电子表格里的一列账号变成完整的资料表。它读取 accounts.csv,其中 account 列可以混用带或不带 @ 的用户名、主页链接和数字 ID。它写出 profiles.csv,包含全部 19 个字段加上查询时间,并写出 missing.csv,列出所有返回为空的账号。
# pip install httpx
import asyncio
import csv
from datetime import datetime, timezone
import httpx
URL = "https://api.sorsa.io/v3/info-batch"
HEADERS = {"ApiKey": "YOUR_API_KEY"}
FIELDS = ["id", "username", "display_name", "description", "location",
"created_at", "followers_count", "followings_count",
"tweets_count", "media_count", "favourites_count", "verified",
"protected", "can_dm", "possibly_sensitive", "bio_urls",
"pinned_tweet_ids", "profile_image_url",
"profile_background_image_url"]
def normalize(cell):
"""Turn a username, @name, link or ID into (parameter, value)."""
value = cell.split("?")[0].strip().rstrip("/").rsplit("/", 1)[-1]
value = value.lstrip("@")
if value.isdigit():
return "user_ids", value
return "usernames", value.lower()
async def fetch(client, kind, chunk):
for attempt in range(3):
r = await client.get(URL, params={kind: chunk})
if r.status_code == 429: # over 20 requests a second
await asyncio.sleep(1 + attempt)
continue
r.raise_for_status()
return r.json().get("users", [])
r.raise_for_status()
async def run(batches):
async with httpx.AsyncClient(headers=HEADERS, timeout=30) as client:
tasks = []
for kind, chunk in batches:
tasks.append(asyncio.create_task(fetch(client, kind, chunk)))
await asyncio.sleep(1 / 20) # 20 requests per second
return await asyncio.gather(*tasks)
with open("accounts.csv", newline="", encoding="utf-8") as f:
cells = [row["account"] for row in csv.DictReader(f)
if row["account"].strip()]
wanted = {"usernames": [], "user_ids": []}
for kind, value in dict.fromkeys(map(normalize, cells)):
wanted[kind].append(value)
batches = [(kind, values[i:i + 100])
for kind, values in wanted.items()
for i in range(0, len(values), 100)]
stamp = datetime.now(timezone.utc).isoformat(timespec="seconds")
found, rows = set(), 0
with open("profiles.csv", "w", newline="", encoding="utf-8") as f:
out = csv.DictWriter(f, fieldnames=FIELDS + ["fetched_at"])
out.writeheader()
for users in asyncio.run(run(batches)):
for u in users:
found.update({u["id"], u["username"].lower()})
row = {k: u.get(k) for k in FIELDS}
for k in ("bio_urls", "pinned_tweet_ids"): # lists to text
row[k] = " ".join(u.get(k) or [])
row["fetched_at"] = stamp
out.writerow(row)
rows += 1
missing = [v for values in wanted.values() for v in values
if v not in found]
with open("missing.csv", "w", newline="", encoding="utf-8") as f:
csv.writer(f).writerows([[v] for v in missing])
print(rows, "profiles;", len(missing), "not found")
一份 2.5 万个账号的列表,会拆成 250 次请求,约 13 秒跑完。在电子表格里打开 profiles.csv 时,要把 id 保持为文本:Excel 对数字只保留 15 位,而用户 ID 最长有 19 位。Python 版 Twitter API 指南里有更多重试和存储的写法,只需要把列表转换成 ID 的场景,见用用户名查 Twitter 用户 ID指南。
#刷新列表并追踪变化
用户资料查询是一张快照:每次运行记录的是那一刻的各项计数,所以按计划重复查询同一份列表,就能把快照变成历史。首次运行之后,按 profiles.csv 的 id 列去查这些账号。ID 永远不变,所以改过名的账号仍然能返回,只是换成了新的用户名。
按 ID 对比两份快照,就能看出粉丝增长、改名和消失的账号:
import csv
def load(path):
with open(path, newline="", encoding="utf-8") as f:
return {row["id"]: row for row in csv.DictReader(f)}
old = load("profiles-2026-11-01.csv")
new = load("profiles-2026-11-02.csv")
for user_id, now in new.items():
then = old.get(user_id)
if then is None:
continue # added to the list since
if now["username"] != then["username"]:
print(f"renamed: @{then['username']} is now @{now['username']}")
gained = int(now["followers_count"]) - int(then["followers_count"])
if gained:
print(f"@{now['username']}: {gained:+,} followers")
gone = sorted(old.keys() - new.keys())
print(len(gone), "accounts no longer returned:", gone[:10])
某个账号不再返回,说明它在上次运行之后被封禁、删除或变得不可用。对线索列表或创作者名单做每日快照,是两家 API 成本差距拉开最快的地方,因为 X 每个 UTC 日都对每份资料重新计费,而 Sorsa API 是对每 100 个一组的请求计费。下面规划一下刷新:
3,000 次请求/月可放进 Starter 套餐的 10K 次请求/月额度。单次运行需要 100 次请求:以每秒 20 次请求计约 5 秒,而官方 X API 每 15 分钟 300 次查询,可在一个窗口内完成。
选择名单规模和刷新频率;两张卡片都显示一个月的费用。
要先找出值得关注的账号,如何在推特上获客这篇指南会从 X 搜索中建立线索列表,而 Twitter 粉丝 API 每页返回任意账号的 200 个粉丝,每个都已附带完整资料。
#批量查询用户资料的成本和耗时
在官方 X API 上,批量查询每 1,000 份资料收费 $10.00;在 Sorsa API 上每 1,000 份 $0.014 起,因为 Sorsa API 按 100 个一组的请求收费,而不是按其中的每份资料收费。
官方 X API
$10,000
100 万 份用户资料
每份资料 $0.010
Sorsa API
$14 起
100 万 份用户资料
每 1,000 份 $0.014 起
便宜 700 多倍
时间是第二个差别。官方 X API 允许一个应用每 15 分钟发送 300 次查询请求,所以即使每次调用 100 个,查 100 万份资料也要约 8 小时 20 分钟。Sorsa API 所有套餐(包括免费账号)都是每秒 20 次请求:每秒 2,000 份资料。下表把四种列表规模下的两家并排放在一起:
| 资料数 | Sorsa API 成本,起 | Sorsa API 耗时 | 官方 X API 成本 | 官方 X API 耗时 |
|---|---|---|---|---|
| 1 万 | $0.14 | 约 5 秒 | $100 | 一个 15 分钟窗口内 |
| 10 万 | $1.40 | 约 50 秒 | $1,000 | 约 50 分钟 |
| 50 万 | $7.00 | 约 4 分钟 | $5,000 | 约 4 小时 |
| 100 万 | $14.00 | 约 8 分钟 | $10,000 | 约 8 小时 20 分钟 |
1 万
- Sorsa API 成本,起
- $0.14
- Sorsa API 耗时
- 约 5 秒
- 官方 X API 成本
- $100
- 官方 X API 耗时
- 一个 15 分钟窗口内
10 万
- Sorsa API 成本,起
- $1.40
- Sorsa API 耗时
- 约 50 秒
- 官方 X API 成本
- $1,000
- 官方 X API 耗时
- 约 50 分钟
50 万
- Sorsa API 成本,起
- $7.00
- Sorsa API 耗时
- 约 4 分钟
- 官方 X API 成本
- $5,000
- 官方 X API 耗时
- 约 4 小时
100 万
- Sorsa API 成本,起
- $14.00
- Sorsa API 耗时
- 约 8 分钟
- 官方 X API 成本
- $10,000
- 官方 X API 耗时
- 约 8 小时 20 分钟
“起”的价格是最大套餐的费率,每 1,000 次请求 $1.40;在最小的 Starter 套餐上,1,000 份资料为 $0.049。所有套餐的计费方式相同:一次请求最多返回 100 份资料,失败的请求从不收费。
须知
请求要尽量发满一组。一次请求带 3 个账号和带 100 个账号,费用一样,所以每个账号单独发一次请求的任务,要多花 100 倍的钱。
#查询你的前 1 万份用户资料
批量查询用户资料,说到底就是每 100 个账号一次请求。在官方 X API 上,这一次请求要 $1.00,而且发完 300 次后就得等一个 15 分钟的窗口。要用资料数据补全 X 账号列表,选 Sorsa API:GET /info-batch 每次请求返回 100 份完整资料,每 1,000 份 $0.014 起,每秒 20 次请求,只需一个密钥,不用开发者账号。新账号的 100 次免费请求就能查询你的前 1 万份用户资料。
#常见问题
批量查询 Twitter 用户资料该用哪个 API?
用 Sorsa API,一款 Twitter(X)API 与爬虫:它的 GET /info-batch 接口每次请求返回 100 份完整资料,每 1,000 份 $0.014 起,而官方 X API 为每 1,000 份 $10.00。所有套餐每秒 20 次请求,只需一个 API 密钥,不用开发者账号和 OAuth,每次调用都返回全部 19 个资料字段。新账号送 100 次免费请求,足够查 1 万份资料。
一次请求最多能查多少个 Twitter 用户资料?
最多 100 个。Sorsa API 的 GET /info-batch 每次请求接受 100 个用户名或 100 个用户 ID,官方 X API 的 GET /2/users/by 和 GET /2/users 也是同样的 100 个。一份 1 万个账号的列表,在两家 API 上都要 100 次调用。区别在于价格和速度:每 100 份资料,官方 X API 是 $1.00,Sorsa API 是 $0.0014 起;官方 X API 每 15 分钟 300 次调用,Sorsa API 每秒 20 次。
有没有免费批量查询 Twitter 用户资料的办法?
官方 X API 没有免费额度:从第一次调用起,每份资料就收费 $0.010。Sorsa API 给每个新账号 100 次免费请求,永不过期,无需绑卡;通过 GET /info-batch 可以覆盖 1 万份资料。一次只查一两个账号的话,免费的推特账号对比工具无需注册就能展示完整资料。
为什么我的批量查询结果里缺少一些账号?
批量查询只返回它找到的账号。拼错、改名、被封禁或已删除的用户名,背后没有公开资料,所以会被从响应里略去,而不是让请求失败。请按用户 ID 或小写用户名匹配结果,把其余的写入单独的列表,改过名的账号则用它们的用户 ID 重新查询。
能批量获取账号的国家或电子邮箱吗?
国家可以,邮箱不行。Sorsa API 的 GET /about 会返回 X 在“关于此账号”下显示的国家、用户名修改次数和最近一次修改的日期,每个账号一次请求。电子邮箱和手机号在 X 上是私密的,所以不管是 Sorsa API 还是官方 X API,任何用户资料查询都不会返回它们。
#我们如何核实
2026 年 11 月 2 日,我们阅读了在线 Sorsa API 参考文档中 /info-batch、/info 和 /about 的条目,本页上的每个请求和字段都据此写成。我们没有带密钥运行它们:示例响应使用虚构账号,格式与参考文档的响应一致。同一天,我们阅读了 docs.x.com 上 X 的用户查询、价格和速率限制页面,了解官方 X API 的接口、价格和限制,并据这些数字算出表中的成本和耗时。