跳转到主要内容

近期搜索分页

介绍

搜索查询通常匹配到的 Post 数量会超过单个 API 响应可返回的上限。出现这种情况时,data 会以一系列“页面”的形式返回。分页是指按页请求以获取完整数据集的方法。 以下是近期搜索分页的基本要点:
  • 近期搜索端点会针对查询至少返回一页结果;如果还有更多页面可用,会在 JSON 响应中提供一个 next_token。为获取所有匹配的 Post,可重复此过程,直到响应中不再包含该 token。
  • next_token 不会过期。无论在何时发起请求,多次使用相同的 next_token 值都会得到相同的结果。
  • Post 按时间逆序、基于 UTC 时区返回。这一点在单个页面内以及跨多个页面都成立: 
    • 第一次响应中的第一个 Post 是与你的查询匹配的最新 Post。
    • 最后一次响应中的最后一个 Post 是与你的查询匹配的最早 Post。
  • 通过 max_results 请求参数可以配置每个响应返回的 Post 数量。默认值为 10,最大为 100。 
  • 任何分页实现都需要从响应负载中解析 next_token,并将其包含在“下一页”的搜索请求中。有关如何构建这些“下一页”请求的更多详情,请见下文。  
近期搜索端点旨在支持两种基本使用模式:
  • 获取历史 - 从关注的时间范围请求匹配的 Post。这类请求通常用于一次性的历史研究。搜索请求可以基于 start_time 和 end_time 请求参数。近期搜索端点将按时间逆序返回 Post,从最新的匹配 Post 开始。 
  • 轮询 - 请求自上一次收到的 Post 以来新发布的匹配 Post。这些用例通常侧重近实时场景,特点是频繁请求以“监听”新的目标 Post。近期搜索端点提供 since_id 请求参数以支持“轮询”模式。为便于按 Post ID 导航,还提供了 until_id 请求参数。  
接下来,我们将讨论历史模式。这是近期搜索端点的默认模式,并用于说明分页的基本原理。随后我们将给出轮询用例的示例。当轮询触发分页时,管理搜索请求还需要增加一步。  

检索历史数据

本节说明如何使用 start_time 和 end_time 请求参数,从特定时间段(目前仅限过去 7 天)检索 Post。历史请求通常为一次性请求,用于研究和分析。  按时间段发起请求是 recent search 端点的默认模式。如果搜索请求未指定 start_time、end_time 或 since_id 参数,则 end_time 默认为“now”(实际为查询时间前 30 秒),start_time 默认为 7 天前。 该端点将按时间倒序返回首个“页面”的 Post,从最新的 Post 开始。如果还有更多页面,JSON 响应负载中还会包含一个 next_token。要收集全部匹配的 Post(无论页数多少),应持续发起请求,直到不再返回 next_token。  例如,以下是一个检索过去一周内包含关键词 snow 的 Post 的初始请求: https://api.x.com/2/tweets/search/recent?query=snow 响应包含最近的 10 条 Post,以及 JSON 响应中的这些“meta”属性:
"meta": {
        "newest_id": "1204860593741553664",
        "oldest_id": "1204860580630278147",
        "next_token": "b26v89c19zqg8o3fobd8v73egzbdt3qao235oql",
        "result_count": 10
    }
要获取接下来的 10 条 Post,请将该 next_token 添加到原始请求中。请求如下: https://api.x.com/2/tweets/search/recent?query=snow&next_token=b26v89c19zqg8o3fobd8v73egzbdt3qao235oql 查找 next_token 并将其包含在后续请求中的流程可以重复执行,直到收集到全部(或指定数量的)Post,或达到设定的请求次数。如果数据完备性(收集到查询的所有匹配项)对你的用例至关重要,那么采用“重复直至 request.next_token 为 null”的简单设计即可。

轮询与监听用例

本节概述如何通过在 recent search 端点中使用 since_id 请求参数进行轮询,以获取最新的 Post。 在轮询用例中,会以持续且高频的方式发起“有新的关注的 Post 吗?”的查询。与基于时间的历史用例不同,轮询用例通常基于 Post ID 发起请求。 轮询模式的核心在于,每个新的 Post 都有一个唯一 ID,该 ID 通常由 X 平台按升序产生。如果一个 Post 的 ID 小于另一个,则表示它发布得更早。 recent search 端点支持按 Post ID 浏览 Post 存档。该端点的响应包含 oldest_id 和 newest_id 两个 Post ID。在轮询模式下,请求会将 since_id 设置为目前收到的最大/最新 ID。 例如,假设每五分钟查询一次关于 snow 的新 Post,而上次我们收到的最后一个 Post 的 Post ID 为 10000。到轮询时,请求如下所示: https://api.x.com/2/tweets/search/recent?query=snow&since_id=10000 接下来,假设自上次请求以来又发布了七个 Post。由于这些都能放在单个 data“页面”中,因此没有 next_token。响应会提供最新(最新发布)Post 的 Post ID:
"meta": {
        "newest_id": "12000",
        "oldest_id": "10005",
        "result_count": 7
    }
要进行下一次轮询查询,需要使用该 newest_id 值来设置下一个 since_id 参数: https://api.x.com/2/tweets/search/recent?query=snow&since_id=12000 当有更多可用数据并提供了 next token 时,只需要第一页结果中的 newest_id 值。每一页数据都会包含 newest_id 和 oldest_id 值,但仅第一页提供的值是下一次按计划进行的轮询请求所需的唯一值。因此,如果你在实现轮询方案,或按 ID 范围搜索 Post,分页逻辑会稍微更复杂。 现在假设又有 18 条匹配的 Post。该 endpoint 将首先返回包含完整一页 data 的响应,并附带一个 next_token,用于在这五分钟时间段内请求下一页数据。它还会包含五分钟后下一次轮询间隔所需的最新 Post ID。
"meta": {
        "newest_id": "13800",
        "oldest_id": "12500",
        "next_token": "fnsih9chihsnkjbvkjbsc",
        "result_count": 10
    }
要收集这五分钟时间段内所有匹配的数据,请在下一次请求中传递 next_token,并保持 since_id 与上一次请求相同的值。 https://api.x.com/2/tweets/search/recent?query=snow&since_id=12000&next_token=fnsih9chihsnkjbvkjbsc
"meta": {
        "newest_id": "12300",
        "oldest_id": "12010",
        "result_count": 8
    }
第二个响应返回了剩余的 8 条 Post,且不包含 next_token。请注意,我们不会更新 newest_id 值(12300),而是基于第一次响应中的 newest_id 值发起下一次 since_id 请求: https://api.x.com/2/tweets/search/recent?query=snow&since_id=13800