要点: X 搜索操作符是按作者、日期、互动、媒体、语言和位置过滤推文的关键词和符号。它们把宽泛的关键词搜索收窄成精确查询,2026 年有超过 50 个在网页上有效。官方 X API v2 只支持一个子集。

作者:Sorsa 编辑部

2026 年 7 月更新:对照 X 的实时搜索行为和官方 X API v2 重新核验了每个操作符、把 Sorsa 定价刷新到当前的每 1,000 批量费率,并加入了 100 次免费请求的起步额度。较早的修订加了常被混淆的操作符一节、扩展了损坏操作符参考,并加了深度分页指引。

多数速查表悄悄跳过对真实工作最要紧的部分:最高价值的操作符是官方 X API v2 不支持的网页搜索操作符。min_faves:min_retweets:、丰富的 since:/until: 日期语法、within_time:filter:blue_verified 全都在 x.com 搜索框里有效,而全都被 /2/tweets/search/recent 静默丢弃。Sorsa API,一个替代性的 Twitter/X API,把完整的网页操作符集直接透传其搜索推文接口,所以本指南里的每个操作符都在生产代码里运行、而不只在网站上。Sorsa 按请求、而非按资源计费,在每个套餐上跑固定的每秒 20 次请求、没有按接口窗口,也不需要开发者账号审批,这就是为什么操作符驱动的数据管道往往把官方 API 抛在后面。

本指南为两类读者而建:想要即用可复制粘贴查询的营销人员,和需要大规模跑那些查询的开发者。下面每个操作符都按过滤内容分组、带可用示例,cookbook 再把它们变成 14 个即跑的查询模式。

为把功劳归于该归之处,本参考取材于真实世界测试加 Igor Brigadir 社区维护的 twitter-advanced-search 参考,那是关于未记录的 X 搜索行为的事实上的行业来源。

目录

  1. X 搜索操作符如何工作
  2. 网页操作符 vs 官方 X API v2 操作符
  3. 关键词、短语和布尔逻辑
  4. 用户和账号过滤
  5. 互动门控
  6. 媒体和内容类型过滤
  7. 日期、时间和 Snowflake ID
  8. 地理过滤
  9. 语言和来源过滤
  10. 卡片和 URL 操作符
  11. 人们弄混的操作符
  12. Cookbook:14 个生产就绪配方
  13. 用 Sorsa API 使用操作符
  14. 构建复杂查询:运算顺序
  15. 2026 年什么损坏或不可靠
  16. 常见问题

X 搜索操作符如何工作 {#how-x-search-operators-work}

X 搜索操作符是你追加到查询上以过滤结果集的小文本命令。它们在三个地方有效:x.com 搜索栏、TweetDeck,以及任何透传完整网页搜索语法的第三方 API,如 Sorsa 搜索推文接口。语法是 operator:value、冒号周围无空格,操作符能自由组合。

操作符落进两大类。独立操作符能单独使用(例如 from:elonmusk 返回一个有效的结果集)。需要连词的操作符必须与至少一个独立操作符一同出现,因为否则会匹配太多内容。这个区别在官方 X API v2 上比在网页上更要紧,但从一开始就理解这一点值得。

三条通用规则:

  • AND 是隐含的。 把两个词并排放(bitcoin etf)要求两者都有。
  • OR 必须大写。 小写 or 被当作字面词。
  • 排除用前导破折号。 crypto -scam 移除含 "scam" 的结果。

如果你计划在生产里用这些,收藏 Sorsa 搜索构建器。这是一个免费、无登录的工具,让你可视化地切换过滤、并生成可复制、带完整操作符覆盖的查询字符串,是在把查询集成进代码之前做原型最快的方式。


网页操作符 vs 官方 X API v2 操作符 {#web-operators-vs-official-x-api-v2-operators}

这是多数速查表不告诉你的最重要的一件事。在 x.com 上有效的 X 高级搜索语法是官方 X API v2 搜索接口所支持的操作符列表的一个超集。如果你在 /2/tweets/search/recent 上构建一条生产环境的数据管道、给它传 min_faves:100 since:2026-01-01 filter:blue_verified,那三个操作符没有一个起作用。这不是错误,而是被静默丢弃。

我们自 2024 年以来在几个迁移项目里见过这个确切的 bug。查询“有效”,在返回推文的意义上,但你以为你有的过滤没了。等有人注意到时,看板已经错了数周。

这是开发者真正在乎的那些操作符逐个对比:

操作符(网页语法)在 x.com / Sorsa 上有效在官方 X API v2 上有效
min_faves:Nmin_retweets:Nmin_replies:N(根本不支持)
since:YYYY-MM-DDuntil:YYYY-MM-DD(用 start_time/end_time 请求参数)
within_time:Xdsince_id:max_id:
filter:blue_verified(仅 is:verified
filter:followsfilter:social有(仅 UI)
filter:has_engagement
filter:imagesfilter:twimgfilter:videosfilter:native_videofilter:pro_video部分(仅 has:mediahas:imageshas:video_link
filter:spaces
card_name:*card_domain:card_url:
near:"city"within:Xkmgeocode:部分(仅 point_radius:bounding_box:place:place_country:
source:client_name
quoted_user_id:(仅 quotes_of_tweet_id:
filter:newsfilter:safe
通配符 "word * word"
from:to:@#$url:lang:
is:retweetis:replyis:quoteis:verified有(有轻微命名差异)有(这些是 API v2 的名字)

对真实工作最大的伤亡是互动过滤(min_favesmin_retweetsmin_replies)和丰富的日期语法。没有 min_faves:,你无法在 API v2 侧高效地浮现爆款或有影响力的内容。你能拉推文并在客户端过滤,但在高量查询上你最终在你立即丢弃的推文上烧掉你的配额,成本差异很快复利。

那个成本差距是具体的。官方 X API v2 按资源计费:一次返回 20 帖加作者资料的搜索花约 $0.30(20 次帖子读取按 $0.005 加 20 次用户读取按 $0.010)。同样的调用在 Sorsa 的 Pro 套餐上是一次请求、约 $0.002,每条推文的作者资料无额外收费地包含。官方 X API v2 还对查询字符串本身施加硬性字符限制(自助近期搜索 512 个字符、全量存档 1,024、仅企业层级 4,096),而网页语法和 Sorsa 的透传只被大约每查询 22 到 23 个操作符的实际操作符上限所界定。如果你需要发帖或发私信,官方 API 仍是那个的工具;对用完整操作符集读取并搜索公开数据,一个像 Sorsa 的 Twitter/X API 替代方案是操作符驱动搜索团队切换的原因。

披露: Sorsa 是我们的产品。我们把这个对比严格保持事实性;缺失操作符列表在本文修订当天对照 X 自己的公开操作符文档可核验。要更深入看那些取舍,见我们的从官方 X API 迁移指南


关键词、短语和布尔逻辑 {#keyword-phrase-and-boolean-logic}

这些是构件。每个高级查询都从这里开始。

操作符它匹配什么示例
keyword keyword含两个词的推文。空格充当隐含 AND。nasa esa
keyword OR keyword含任一词的推文。OR 必须大写。bitcoin OR ethereum
"exact phrase"按那个顺序含精确短语的推文。也阻止自动更正。"state of the art"
-keyword排除含该词的推文。对短语和其他操作符有效。crypto -scam
( )为复杂布尔逻辑给词分组。(AI OR "machine learning") lang:en
"word * word"一个引号短语内的通配符。* 替换任意单个词。"this is the * time"
+word强制精确匹配,阻止 X 的自动更正和词干提取。+radiooooo
#hashtag匹配一个特定话题标签。#tgif
$cashtag匹配一个股票或加密符号。$TSLA

几条绊倒人们的实际说明。 复数匹配单数、反之亦然:bulls 会匹配 bull。X 有时静默地把常见词重新解释为内容意图,所以搜 photo 可能返回带附图的推文、即便文本里没有 "photo" 一词;把这样的词裹进双引号来强制字面匹配。操作符也不严格绑定到推文正文:还能对作者的显示名、屏幕名,和推文内展开的 URL 匹配,这是意外结果的常见来源。

操作符计数上的上限是真实的。一旦你在单个查询里越过大约 22 到 23 个操作符,X 开始静默忽略字符串的尾部。如果你需要比那更多,拆成多次 API 调用、在下游合并结果。


用户和账号过滤 {#user-and-account-filters}

这些按谁发帖、他们回复谁,或谁被提及过滤推文。

操作符说明示例
from:username由一个特定账号发送的推文(不带 @)。from:elonmusk
to:username回复一个特定账号的推文。to:openai
@username在文本任意处提及一个特定账号的推文。@sorsa_app
list:ID来自一个公开 X 列表成员的推文。用 URL 里的数字列表 ID。list:715919216927322112
filter:verified只来自传统认证账号(2023 年前的蓝勾)。AI filter:verified
filter:blue_verified只来自 X Premium(付费蓝标)订阅者。crypto filter:blue_verified
filter:follows只来自你关注的账号。仅 UI,不能被取反。filter:follows
filter:social来自你算法扩展的网络。对"Top"结果有效、不对"Latest"。filter:social

品牌监控技巧。@ 或引号品牌名与 -from: 结合来找除品牌自己之外每个人关于品牌说什么:"Tesla" -from:tesla。那一招就是可行动信号和公关噪音之间的差别,也是多数社交聆听搭建的支柱。

要更深入处理提及追踪,见关于追踪提及的文档;当你想把每个成员的推文放进一条信息流时,list: 操作符与 X 列表 API 自然配对。


互动门控 {#engagement-gating}

按最低(或最高)互动过滤。这些对切穿噪音和浮现爆款内容至关重要,也是官方 X API v2 上最常缺失的操作符。

操作符说明示例
min_faves:N最低点赞数。AI min_faves:100
min_retweets:N最低转推数。crypto min_retweets:50
min_replies:N最低回复数。"product launch" min_replies:20
-min_faves:N最高点赞(取反形式)。bitcoin -min_faves:1000
-min_retweets:N最高转推。news -min_retweets:500
-min_replies:N最高回复。tech -min_replies:100
filter:has_engagement至少有一次互动的推文。能被取反来找零互动推文。from:username filter:has_engagement

如何设阈值。 从低起(min_faves:10)、迭代增加。X 报告在大约 1,000 以上变得近似,所以别过度调优。如果你只想要靠自己内容而非通过放大赢得互动的推文,与 -filter:retweets 结合。在我们自己的数据管道工作里,min_faves:N-filter:retweets-filter:replies 的组合是浮现原创爆款内容最有用的那个过滤;其余都是装饰。


媒体和内容类型过滤 {#media-and-content-type-filters}

X 对什么类型的内容出现在你结果里有异常细粒度的控制。玄机是网页操作符集比 API v2 等价物丰富得多。

媒体过滤

操作符说明
filter:media所有媒体类型(图像、视频、GIF)。
filter:images所有图像,包括第三方链接(例如 Instagram)。
filter:twimg只有原生 X 图像(pic.twitter.com 链接)。
filter:videos所有视频类型:原生 X 视频、YouTube 嵌入等等。
filter:native_video只有 X 自有视频(原生上传、旧 Vine、旧 Periscope)。
filter:consumer_video仅 X 原生视频(排除 pro/Amplify)。
filter:pro_video仅 X pro 视频(Amplify)。
filter:spacesX Spaces 音频内容。
filter:links含任意 URL 的推文。包括媒体 URL;用 -filter:media 来隔离非媒体链接。
card_name:animated_gif具体匹配 GIF。

推文类型过滤

操作符说明
filter:replies只有回复另一条推文的推文。
-filter:replies排除回复(只显示顶层原创推文)。
filter:nativeretweets只有原生转推(通过转推按钮创建)。
include:nativeretweets在结果里包含原生转推(默认被排除)。
filter:retweets旧式 RT 转推加引用推文。
-filter:retweets完全排除转推。
filter:quote只有引用推文。
quoted_tweet_id:ID按 ID 对一条特定推文的引用。
quoted_user_id:ID按用户 ID 对一个特定用户的所有引用。
conversation_id:ID一个话题串里的所有推文(直接回复和嵌套回复)。

特殊内容过滤

操作符说明
card_name:poll2choice_text_only含 2 选文本投票的推文。
card_name:poll3choice_text_only3 选文本投票。
card_name:poll4choice_text_only4 选文本投票。
card_name:poll2choice_image2 选图像投票。
filter:news链接到已识别新闻域名的推文。
filter:safe排除 NSFW 或潜在敏感内容。不是保证。
filter:hashtags只有含至少一个话题标签的推文。
filter:mentions只有含任意 @ 提及的推文。

日期、时间和 Snowflake ID {#date-time-and-snowflake-ids}

精确的基于时间的过滤对事件分析、活动追踪和历史数据提取至关重要。这也是官方 X API v2 分歧最尖锐之处:API v2 期待 start_timeend_time 作为单独的请求参数、且不理解查询字符串里的 since: / until:。网页语法和 Sorsa 支持完整集。

操作符格式说明
since:YYYY-MM-DDsince:2026-01-01在此日期当天或之后发布的推文(含)。
until:YYYY-MM-DDuntil:2026-03-01在此日期之前发布的推文(不含)。
since:YYYY-MM-DD_HH:MM:SS_UTCsince:2026-03-05_12:00:00_UTC带时区的精度时间戳。
since_time:UNIXsince_time:1142974200在一个特定 Unix 时间戳(秒)之后。
until_time:UNIXuntil_time:1142974215在一个特定 Unix 时间戳之前。
within_time:Xdwithin_time:2d在过去 X 天内。也支持 h(小时)、m(分钟)、s(秒)。
since_id:IDsince_id:1234567890在一个特定 Snowflake ID 之后(不含)。
max_id:IDmax_id:1234567890在一个特定 Snowflake ID 当时或之前(含)。

Snowflake ID 技巧

X 上每个推文 ID 都是一个以毫秒精度编码创建时间戳的 Snowflake ID。转换公式:

text
millisecond_epoch = (tweet_id >> 22) + 1288834974657

这有用有两个原因。第一,你能不做一次 API 调用就计算任意推文的确切发布时间,这对按时间去重或排序的回填作业很方便。第二,since_id:max_id: 给你结果窗口上推文级、而非日期级的边界。当你在数小时里对一个高量关键词分页、想精确从停下之处恢复而不重新取回已见过的推文时,这无价。

要更深入走一遍拉取历史推文集,见我们关于搜索旧推文的指南。


地理过滤 {#geographical-filters}

在你深入这里之前先来一次现实核查:只有估计 1 到 2 percent 的推文携带精确地理定位数据。X 于 2019 年 6 月从主 iOS 和 Android 应用移除了精确位置标记,而多数用户一开始就从未选择加入。地理过滤仍有用,但预期覆盖稀薄。

操作符说明示例
near:"city"在一个命名地点附近地理标记。支持短语。near:"San Francisco"
near:me在你当前位置附近(仅 UI)。near:me
within:Xkmnear: 的半径限制。接受 kmmiearthquake near:Tokyo within:50km
geocode:lat,long,radius用坐标精确定位。geocode:37.77,-122.41,5km
place:ID按 X Place 对象 ID 搜索。place:96683cc9126741d1(美国)

在结构化 API 侧,官方 X API v2 用一套不同的地理集(place_country:point_radius:bounding_box:)取代网页 near:/within:/geocode: 操作符。Sorsa 通过 query 字段接受网页地理操作符,即在 x.com 搜索框里有效的那些;API v2 形式在上面的对比表里展示。

一个有用的回退行为。 如果一条推文没有精确坐标,搜索回退到反向地理编码用户的资料位置,所以你可能收到基于作者陈述的位置、而非推文实际来源匹配的推文。那有时是你想要的、有时令人困惑。要用更高覆盖的方法来映射受众所在,见按国家的受众地理


语言和来源过滤 {#language-and-source-filters}

语言

X 用 2 字母 ISO 639-1 代码:lang:enlang:eslang:frlang:delang:jalang:ru 等等。也有几个值得知道的非标准代码:

代码含义
lang:und未定义语言(仅表情符号或仅媒体的推文)。
lang:qme仅带媒体链接的推文(自 2022 年起)。
lang:qst非常短文本的推文。
lang:qht仅带话题标签的推文。
lang:qam仅带提及的推文。
lang:qct仅带 cashtag 的推文。
lang:zxx仅带媒体或一个 Twitter 卡片、无额外文本的推文。

一个高信号用法:from:user lang:zxx filter:images 返回是一张图像、别无他物的推文,零文本噪音。不过 X 的语言检测不完美。短推文、代码片段和表情符号密集的帖子经常被误分类,所以对关键应用,在取回后对正文跑你自己的语言检测。

来源(发帖客户端)

操作符说明示例
source:client_name按发帖所用的应用过滤。空格用下划线。source:Twitter_for_iPhone

常见值:Twitter_for_iPhoneTwitter_for_AndroidTwitter_Web_AppTweetDecktwitter_ads。注意 source: 有时需要旁边另一个操作符才返回结果。


卡片和 URL 操作符 {#card-and-url-operators}

这些对 Twitter 卡片元数据匹配:附在含链接、媒体和嵌入内容的推文上的丰富预览。两件事先知道:card_name: 通常只对最近 7 到 8 天的推文有效;url: 对域名有效、但对长 URL 路径不可靠。

操作符说明
card_domain:domain匹配一个 Twitter 卡片里的域名。基本等价于 url:
card_url:domain类似 card_domain:、但可能返回不同的结果。
card_name:audio带播放器卡片(Spotify、SoundCloud 等等)的推文。
card_name:player带任意播放器卡片的推文。
card_name:summary小图摘要卡片。
card_name:summary_large_image大图摘要卡片。
card_name:promo_website推广网站卡片(通常经 Ads 发布)。
card_name:promo_image_convo带图像的对话式广告卡片。
card_name:promo_video_convo带视频的对话式广告卡片。
url:domain匹配 URL。对域名和子域名有效。连字符必须换成下划线(例如 url:t_mobile.com)。

人们弄混的操作符 {#operators-people-mix-up}

少数操作符看起来可互换、实际不是。这些是悄悄损坏数据集的成对项,所以对每一个精确值得。

filter:verified vs filter:blue_verified filter:verified 匹配持有传统认证的账号(2023 年前认证的记者、公众人物、组织)。filter:blue_verified 匹配任何订阅付费 X Premium 的人。多数品牌监控和编辑查询想要 filter:verified 作信号、而非 filter:blue_verified,后者包括任何付费用户。要干净地隔离传统账号,把两者结合:filter:verified -filter:blue_verified

-filter:retweets vs include:nativeretweets vs -is:retweet -filter:retweets(网页语法)排除旧式 "RT" 文本转推和原生转推两者。include:nativeretweets 把原生转推加回默认排除它们的结果集。-is:retweet 是排除转推的官方 X API v2 拼法,比 filter:retweets 更窄,后者历史上也扫进引用推文。对网页侧干净的原创内容集,用 -filter:retweets;要追踪一条推文传播多远,用带紧时间窗口的 filter:nativeretweets

within_time:Xd vs since:/until: within_time:7d 是一个从查询运行那一刻测量的滚动窗口,所以同一个查询明天返回与今天不同的推文集。since:until: 是固定的日历边界。对可复现的研究数据集,总是偏好显式的 since:/until: 日期胜过 within_time:

from:user vs @user from:user 只返回由那个账号所写的推文。@user 返回任何提及那个账号的推文,包括别人的回复和引用推文。用 from: 做时间线分析、用 @ 做品牌监测;在常见词用户名上,给 @ 查询加 lang:en 或小的互动下限来切噪音。

filter:retweets vs -is:retweet filter:retweets 是匹配转推的网页语法;-is:retweet 是排除它们的 API v2 语法。两者不是完美的互逆,所以要在网页侧排除每种形式的放大,把 -filter:retweets-filter:quote 配对。

这些操作符按互动类型过滤推文。取回一条给定推文背后的实际回复、引用和转推者是一个单独的任务,由专门接口处理、并在 Twitter 互动 API 指南里覆盖。


Cookbook:14 个生产就绪配方 {#cookbook-14-production-ready-recipes}

操作符孤立时有用,组合时强大。以下是我们自己构建过或在客户数据管道里见过的十四个查询模式。复制、换掉变量,直接粘进 X 搜索栏或 Sorsa 搜索接口。

1. 品牌和声誉监控

找关于一个品牌的原创爆款内容,排除品牌自己的帖子和转推噪音:

text
("Tesla" OR "Elon Musk") min_faves:500 filter:links lang:en -from:tesla -filter:nativeretweets

2. 竞品线索生成

找正主动询问你领域里替代品的用户:

text
("notion" OR "obsidian") "?" -filter:links -from:notionhq lang:en

3. 高意向买家发现

找读起来像一个产品类别买入信号的推文:

text
("looking for" OR "anyone use" OR "recommend") ("twitter api" OR "x api") -filter:retweets lang:en

4. 影响者发现

一个话题里认证账号的高互动原创帖:

text
"machine learning" filter:blue_verified min_faves:200 -filter:replies -filter:retweets lang:en

5. OSINT 和突发新闻

用来自认证来源的视觉证据追踪实时事件:

text
"breaking news" filter:images filter:blue_verified within_time:6h

6. 来自 X 列表的内容策划

找一个特定列表成员发布的爆款视频:

text
list:715919216927322112 (filter:videos OR card_name:animated_gif) min_retweets:50

7. 开发者故障排查

找链接到 GitHub 的错误相关对话:

text
url:github.com "error" lang:en filter:replies

8. 带互动门控的加密情绪

追踪关于一个代币的带情绪对话,为实质而过滤:

text
(bitcoin OR $BTC) (bullish OR bearish OR crash OR moon) min_faves:20 lang:en since:2026-01-01 -filter:retweets

9. 超本地监控

在一个紧时间窗口里一个特定地点附近在说什么:

text
"traffic" near:"London" within:5km since:2026-03-05_12:00:00_UTC

10. 找一个特定用户的引用推文

对 URL 形式模式匹配、并排除该用户自己的用户名:

text
twitter.com/elonmusk/status/ -from:elonmusk

11. 仅原创话题串主帖

找发起话题串(非回复、非转推)并赢得真实互动的推文:

text
"your topic" min_replies:10 -filter:replies -filter:retweets lang:en

12. 追踪一个产品发布窗口

用一个互动下限捕捉一个特定日期范围里的所有对话:

text
"product name" since:2026-02-10 until:2026-02-17 lang:en min_faves:5

13. 零互动垃圾检测

识别可疑的低质量发帖(对审核流程有用):

text
"buy now" -filter:has_engagement filter:links lang:en

14. 招聘板挖掘

一个特定技术领域里的招聘信号推文:

text
("hiring" OR "we're looking for") ("react" OR "typescript") -filter:retweets lang:en min_faves:5

跨全部十四个的模式:从话题起、叠加互动、叠加内容类型,然后叠加排除。排除通常正是把嘈杂的结果集和可用的分开的东西。


用 Sorsa API 使用操作符 {#using-operators-with-the-sorsa-api}

上面列出的每个操作符都在 Sorsa /v3/search-tweets 接口的 query 字段里有效。把你完整的查询字符串放进 POST 请求的体里、经 next_cursor 分页,并用短重试处理 429。关于排序、分页和结果处理的更广工作流,通过 API 搜索推文的指南端到端走一遍。

一个用 curl 的最小调用:

bash
curl -X POST https://api.sorsa.io/v3/search-tweets \
  -H "ApiKey: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "(AI OR \"machine learning\") min_faves:100 lang:en -filter:retweets",
    "order": "popular"
  }'

Python:带分页和重试的生产就绪

这是我们在生产里跑的模式,翻遍完整结果集、在限速时重试,并浮现硬错误:

python
import requests
import time
from typing import Iterator

API_KEY = "YOUR_SORSA_API_KEY"
BASE_URL = "https://api.sorsa.io/v3/search-tweets"


def search_tweets(query: str, order: str = "latest") -> Iterator[dict]:
    """
    翻遍每一条匹配查询的推文。
    在 429(速率限制)时带 1 秒等待重试。
    """
    cursor = None
    while True:
        payload = {"query": query, "order": order}
        if cursor:
            payload["next_cursor"] = cursor

        response = requests.post(
            BASE_URL,
            headers={"ApiKey": API_KEY, "Content-Type": "application/json"},
            json=payload,
            timeout=30,
        )

        if response.status_code == 429:
            time.sleep(1.0)
            continue

        response.raise_for_status()
        data = response.json()

        for tweet in data.get("tweets", []):
            yield tweet

        cursor = data.get("next_cursor")
        if not cursor:
            break


# 用法:采集来自 2026 年 1 月的爆款 AI 推文
for tweet in search_tweets(
    '(AI OR "machine learning") min_faves:1000 lang:en '
    'since:2026-01-01 until:2026-02-01'
):
    print(tweet["id"], tweet["likes_count"], tweet["full_text"][:80])

JavaScript / Node.js:异步迭代器模式

javascript
const API_KEY = "YOUR_SORSA_API_KEY";
const BASE_URL = "https://api.sorsa.io/v3/search-tweets";

async function* searchTweets(query, order = "latest") {
  let cursor = null;

  while (true) {
    const payload = { query, order };
    if (cursor) payload.next_cursor = cursor;

    const res = await fetch(BASE_URL, {
      method: "POST",
      headers: { ApiKey: API_KEY, "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });

    if (res.status === 429) {
      await new Promise((r) => setTimeout(r, 1000));
      continue;
    }
    if (!res.ok) throw new Error(`Sorsa API error: ${res.status}`);

    const data = await res.json();
    for (const tweet of data.tweets ?? []) yield tweet;

    cursor = data.next_cursor;
    if (!cursor) break;
  }
}

// 用法
for await (const tweet of searchTweets(
  '"product launch" min_faves:50 lang:en since:2026-02-10'
)) {
  console.log(tweet.id, tweet.likes_count);
}

深度分页不可靠:改为按日期分块

在任何高量历史拉取上要规划的一件事:X 的搜索分页对深度结果集不稳定。这是每条访问路径都继承的上游平台行为、而非某一个 API 的怪癖。过了单个游标链的大约头十几页,你开始看到重复、或链条提前停止,远在结果集耗尽之前。

修法是停止依赖一条长游标链、改为把查询拆成按日期范围的块。跑几个更小的查询、每个由 since:until: 界定,并在各自新鲜的游标上给每块分页:

python
from datetime import date, timedelta


def chunked_search(query_base: str, start: date, end: date, chunk_days: int = 7):
    """把一个长日期范围拆成每周块,每块有它自己的游标链。"""
    current = start
    while current < end:
        chunk_end = min(current + timedelta(days=chunk_days), end)
        full_query = (
            f"{query_base} since:{current.isoformat()} until:{chunk_end.isoformat()}"
        )
        yield from search_tweets(full_query, order="latest")
        current = chunk_end


# 2026 年第一季度,逐周,无深游标不稳定
for tweet in chunked_search(
    'openai min_faves:200 lang:en', date(2026, 1, 1), date(2026, 4, 1)
):
    print(tweet["id"])

对连一周都太宽的快动事件,用完整时间戳形式降到每小时块(since:2026-03-01_12:00:00_UTC until:2026-03-01_13:00:00_UTC)。每块都可复现且可恢复,当你在重建一次发布或新闻事件的时间线时这要紧。对需要快照特定推文、而非搜索它们的存档管道,tweet-info-bulk 接口每次请求接受最多 100 个推文 ID。


构建复杂查询:运算顺序 {#building-complex-queries-order-of-operations}

一旦你开始堆五六个操作符,求值顺序就开始要紧。X 上的规则和多数搜索引擎一样:AND 比 OR 绑定得更紧

那意味着 cat OR black dog 被求值为 cat OR (black dog)、而非 (cat OR black) dog。如果你想要第二种解释,加括号:(cat OR black) dog。拿不准时,用括号,它不花你什么、且消除歧义。

一个对几乎每个查询都有效的构造顺序:

  1. 在括号里给核心关键词分组(bitcoin OR ethereum OR $BTC)
  2. 加内容约束: lang:enfilter:images-filter:replies
  3. 设互动阈值: min_faves:50min_retweets:10
  4. 排除噪音: -from:spambot-scam-airdrop-filter:retweets
  5. 需要时加时间界限: since:2026-01-01 until:2026-03-01

一致地遵循这个顺序,你就能一眼读懂你的任何查询、并更快发现错误。


2026 年什么损坏或不可靠 {#what-is-broken-or-unreliable-in-2026}

操作符在 X 上悄然失败。查询仍返回推文,所以损坏的过滤看起来像能用的,直到数据已经错了。以下失败模式值得在咬住你之前知道。

不再按名字所暗示行事的操作符:

操作符2026 年状态原因
filter:vine仅历史Vine 在 2017 年关闭;只匹配存档的 2017 年前内容。
filter:periscope仅历史Periscope 在 2021 年关闭。
near:within:geocode:覆盖减少精确地理标记于 2019 年 6 月从 iOS 和 Android 应用移除;只有 1 到 2 percent 的推文携带坐标。
filter:nativeretweets大约 7 到 10 天X 只短期保留原生转推数据。
card_name:*card_domain:大约 7 到 8 天卡片元数据保留期短。
filter:verified不一致传统认证和付费蓝标在 2023 年更名后被混为一谈;用 filter:verified -filter:blue_verified 来隔离传统账号。

常见的“搜索不工作”情形及实际发生了什么:

  • 你在"Top"而非"Latest"上。 默认的 Top 标签显示算法选择、并隐藏多数匹配,读起来像缺失结果。切到 Latest 标签、或在 API 上传 order: "latest",以获得完整覆盖。
  • 引号里的一次精确短语搜索返回空。 引号强制一次精确 token 匹配并禁用拼写更正,所以 X 没有精确匹配的短语回来为空。移除引号、或用通配符形式 "word * word" 来松开匹配。
  • from: 返回空或垃圾。 最常见的起因是冒号后的空格:写 from:username、绝不 from: username,因为空格弄坏操作符。第二常见的起因是该账号没发帖的日期范围。
  • geocode:near: 几乎不返回什么。 地理覆盖在 2019 年后崩了;对位置工作,倚重资料位置回退、或按国家分析受众所在、而非按推文级坐标。
  • 查询在 x.com 上有效、但在官方 X API v2 上不有效。 几乎总是一个 API 静默丢弃的仅网页操作符;见上面的网页对 API v2 对比表

再来几个持久的坑:

  • 操作符上限: 查询支持大约 22 到 23 个操作符。越过之后、查询的尾部被静默忽略。
  • 私密和被封账号被排除于所有搜索结果之外;没有操作符组合触达它们。
  • 不是所有推文都被索引。 因平台或反垃圾原因被标记的帖子被排除于搜索之外、即便技术上仍在线。当追逐被互动阻断的账号时这是一个已知缺口(相关上下文见我们关于 Twitter“此请求看起来可能是自动化的”错误的报道)。
  • 自动更正在某些情形下静默发生;+word"word" 来强制精确匹配。
  • URL 匹配脆弱。 域名和子域名有效,长 URL 路径不有效,而域名里的连字符必须换成下划线(url:t_mobile.com)。

实战中

我们合作过的一个大约 12 人的社交分析团队在官方 X API v2 上构建了一块品牌监控看板。他们的查询用 min_faves:filter:blue_verified 来只浮现值得一次人工回复的高信号提及。在 API v2 上,那两个都是被静默丢弃的仅网页操作符,所以数周里“顶部提及”面板在摄入每一条低互动提及、而优先级实际上是随机的。没人看到错误,因为没有。把同样的查询字符串搬到一个接受完整网页操作符集的搜索 API,就修好了问题、无需重写任何过滤逻辑。因为计费是按请求、而非按资源,同样的监控量只花了按帖读取官方定价的一小部分。这个失败恰恰是隐形的,因为损坏的操作符正是官方 API 一开始就从未支持的那些。


常见问题 {#faq}

什么是 X 高级搜索?

X 高级搜索是平台按作者、日期、互动、媒体类型、语言和位置过滤推文的内置方式。X 高级搜索作为表单在 x.com/search-advanced 可用,或你能从任何地方把同样的操作符直接打进搜索栏。一旦你知道语法,打操作符比填表单更快。

如何按日期搜索 Twitter?

要按日期搜索 Twitter,在一个查询里结合 since:YYYY-MM-DDuntil:YYYY-MM-DD,例如 "product launch" since:2026-02-10 until:2026-02-17since: 日期是含的、until: 日期是不含的,所以推文必须在 until 日期之前、而非当天发布。对亚日精度,用时间戳形式 since:2026-02-10_14:00:00_UTC

为什么搜索操作符在官方 X API 上不工作?

min_faves:min_retweets:since:until:within_time:filter:blue_verifiedcard_name: 这样的操作符是官方 X API v2 不支持的网页搜索操作符;官方 API 静默忽略、而非返回错误。Sorsa 的搜索接口接受完整网页操作符集,这就是为什么跑按互动过滤或按日期界定管道的团队离开官方 API。

如何不用 X 账号找旧推文?

X 在 2026 年对多数搜索要求登录,包括基础搜索栏。两个选项在没有你自己账号的情况下有效。第一,对你已有的特定推文 URL 用互联网档案馆的 Wayback Machine。第二,用维护自己公开搜索索引访问的第三方 Twitter/X API(如 Sorsa),把历史结果作为结构化 JSON 返回。

filter:retweets-is:retweet 有什么区别?

filter:retweets 是匹配转推的网页搜索语法,-is:retweet 是排除它们的官方 X API v2 语法。两者不是精确互逆:filter:retweets 历史上包括旧式 "RT" 转推和引用推文两者,API v2 is:retweet 更窄。要在网页侧排除每种形式的放大,把 -filter:retweets -filter:quote 一起用。

一个查询里能组合多少个搜索操作符?

X 在单个查询里大约 22 到 23 个之后开始静默忽略操作符,所以过长查询的尾部被无错误地丢弃。官方 X API v2 还把查询字符串本身封顶在自助近期搜索 512 个字符、全量存档 1,024,而仅企业层级 4,096。

有支持完整搜索操作符集的 Twitter/X API 吗?

有。官方 X API v2 只支持一个搜索操作符子集,但 Sorsa 的搜索推文接口透传完整网页操作符集,包括 min_faves:since:/until:filter:blue_verified。Sorsa 在每个套餐上跑固定的每秒 20 次请求、没有按接口窗口也没有开发者账号审批,并无额外成本地返回每条推文的作者资料。


审校:Keksich(Sorsa 创始人,X API 研究者)

来源以及我们如何核查这个

本指南取材于我们打造并运行一个替代性 Twitter/X API 的亲手工作(自 2022 年以来服务超过 50 亿次请求)、对着我们实时搜索推文接口测试,加上 Igor Brigadir 社区维护的 twitter-advanced-search 参考和官方 X API v2 操作符文档。这里列出的每个操作符都在 2026 年 6 月对照 X 当前的搜索行为重新核对,而网页对 API v2 差异在本次修订当天对照 X 自己发布的操作符列表核验。如果你想把操作符参考与接口参考放在一起,Sorsa 文档里也有。


开始上手

把这份速查表投入使用最快的方式:

  1. 打开搜索构建器、可视化地组装查询。无登录,构建也无速率限制。
  2. Sorsa Playground 里运行、看带 JSON 和 CSV 导出的实时结果。
  3. 当你准备好编写脚本时,把你的查询放进上面的 Python 或 JavaScript 示例、用你的 API 密钥调用搜索接口。每个账号注册即送 100 次免费请求:无需绑卡、永不过期、跨全部 40 个接口有效,且足够最多 1 万条推文或 2 万份资料。如果你还没创建密钥,快速上手走一遍密钥创建。

来自官方 X API v2、厌倦了静默什么都不做的操作符?迁移指南逐接口映射差异,而在批量接口上 Sorsa 折合每 1,000 条推文从 $0.02 起、每 1,000 份资料从 $0.01 起,在固定每秒 20 次请求的速率限制上、无审批队列。完整定价是公开的。