跳到正文

如何获取回溯到 2006 年的 Twitter 历史数据

Twitter 历史数据可回溯到 2006 年 3 月 21 日的第一条推文:仍在线的每一条公开帖子,都能通过全量归档搜索 API 按关键词、账号和日期范围取回,而已删除和受保护的帖子则不在其中。

  • 更新于
  • 发布于
  • 阅读约 11 分钟

简短回答: 没有人把完整的归档作为一个文件出售:你得按关键词和日期,去搜索你需要的那一段。官方 X API 对这种搜索按每 1,000 条帖子 $5.00 计费,每月封顶 300 万条。要做回填,用 Sorsa API,一款 Twitter(X)API 与爬虫:通过 POST /search-tweets,每 1,000 条推文 $0.07 起,并有 100 次免费请求可以先试。

接口
POST /search-tweets
每页条数
每次请求约 20 条推文
价格
每 1,000 条 $0.07 起

#Twitter 历史数据能回溯多远

Twitter 的历史数据始于 2006 年 3 月 21 日,也就是第一条推文发出的那天,从那时起仍在线的每一条公开帖子,都能通过搜索找到。没有人把完整归档当作文件发放,所以你要取回自己需要的那一段:按查询、按账号,或按推文 ID。

有三类帖子,任何 API 和任何工具都拿不到:作者已删除的推文、受保护账号的帖子,以及被封禁账号的帖子。同一份数据集,2019 年采集一次,今天再采集一次,结果会变少,原因正是如此。

只是手动查几条的话,免费的 Twitter 高级搜索工具能在浏览器里运行同样的日期运算符。任何要统计、画图或用来训练模型的数据,都需要 API。

2014 年的一条推文,现在会返回什么

无论用哪个 API,历史推文返回时,正文和日期都与发布时完全一致,但互动计数和作者资料是今天的。

推文的组成部分一条 2014 年发布的推文,你能得到什么
正文、日期、ID、链接和媒体与 2014 年发布时一致
点赞、转发、回复和引用计数今天的总数,不是 2014 年当时的计数
作者:用户名、简介、粉丝数作者今天的资料,包括改过的用户名
  • 正文、日期、ID、链接和媒体

    一条 2014 年发布的推文,你能得到什么
    与 2014 年发布时一致
  • 点赞、转发、回复和引用计数

    一条 2014 年发布的推文,你能得到什么
    今天的总数,不是 2014 年当时的计数
  • 作者:用户名、简介、粉丝数

    一条 2014 年发布的推文,你能得到什么
    作者今天的资料,包括改过的用户名

所以,研究 2014 年某个话题标签如何传播时,可以精确统计每天的推文数。但无法从归档里读出 2014 年的粉丝数,因为推文从来没有存储过这个数字。如果将来需要某个时间点的数据,请在推文出现时就采集,并自己保存计数。

#获取历史推文的三种方式

要获取历史推文,用 Sorsa API:一个 API 密钥就能触达回溯到 2006 年的每一条公开推文,所有套餐统一每秒 20 次请求,搜索每 1,000 条 $0.07 起。用哪个接口,取决于你手里有什么:一个话题和日期范围、一个账号,还是一批推文 ID,而且每条推文都带着作者的完整资料返回。

话题用搜索,账号读时间线,已发布的数据集查 ID。按 ID 查询的每条推文成本最低。

搜索覆盖了大多数研究:选举期间的某个话题标签、2019 年某个品牌的提及、五年间的某个 cashtag。账号这条路线从最新到最早,读取一条时间线。ID 这条路线用来重建别人已发布的数据集,每条推文成本最低,因为一次请求带 100 条推文。

#如何用 API 搜索历史推文

用 Sorsa API 搜索归档,四步、一个密钥,没有一步需要 X 账号、应用审核或 OAuth。同一个接口也能做实时搜索,我们的 Twitter 搜索 API 指南对此有介绍。

  1. 获取密钥。 注册后,从控制台复制你的 API 密钥。100 次免费请求已经在上面了。

  2. 写好查询。 先写关键词,再写时间窗口:since:2014-04-01 包含那一天,until:2014-05-01 在那一天之前停止,都按 UTC 计算。可以用 from:、lang:、min_faves: 或 -filter:retweets 来收窄;每个运算符都在我们的 Twitter 搜索运算符列表里。

  3. 发送第一个请求。 把查询 POST 到 POST /search-tweets(在新标签页打开),并带上 "order": "latest",这样各页就会按时间顺序走完这个窗口。

    Terminal
    curl -X POST "https://api.sorsa.io/v3/search-tweets" \
      -H "ApiKey: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "query": "\"rainfall survey\" since:2014-04-01 until:2014-05-01",
        "order": "latest"
      }'
    
    Response200 OK
    {
      "tweets": [
        {
          "id": "456721912166192197",
          "full_text": "Day 3 of the rainfall survey: 41 mm in the valley.",
          "created_at": "2014-04-17T09:12:44Z",
          "lang": "en",
          "likes_count": 38,
          "retweet_count": 12,
          "reply_count": 4,
          "quote_count": 1,
          "is_reply": false,
          "user": {
            "id": "583920117",
            "username": "mira_archive_notes",
            "display_name": "Mira Field Notes",
            "followers_count": 2214,
            "created_at": "2012-06-02T18:40:11Z"
          }
        }
      ],
      "next_cursor": "DAADDAABCgABGEZx0iWAJ8kKAAIYRm0eqZvwRg"
    }
    
  4. 翻页走完整个窗口。 在请求体里带上 next_cursor 和同样的查询再发,直到某个响应不再带它就停下。每页约 20 条推文,数量会有变化,所以一页偏短,并不代表窗口已经取完。

返回 403,表示密钥缺失、错误或请求次数已用完;返回 429 表示一秒内发了超过 20 次请求,等一秒再重新发送。

须知

做回填时请用 "order": "latest":它会按时间顺序走完一个日期窗口,这正是完整采集的做法。"popular" 把互动最多的推文排在前面,适合找出某段时间里的热门帖子,不适合统计其中的每一条帖子。

#如何回填多年的推文而不留缺口

回填多年的数据,最好拆成许多小的日期窗口,每个一个月或一周,逐个翻到底,一次保存一个。这样,失败的窗口可以单独重跑,每个窗口都能用条数核对,而且因为 until: 不包含它所在的那一天,首尾相接的窗口不会把同一条推文保存两次。

一次一个月:每个窗口翻到最后一个 cursor 再保存,所以崩溃只损失一个月,而不是整个任务。

下面的脚本逐月走过一段日期范围,并用 next_cursor 翻完每个窗口。它每个月写一个 JSON Lines 文件,并跳过磁盘上已有的月份,所以你可以随时停下,再重新启动。

import json
import os
import time
from datetime import date

import requests

URL = "https://api.sorsa.io/v3/search-tweets"
HEADERS = {"ApiKey": "YOUR_API_KEY"}


def months(start, end):
    """Yield (since, until) pairs, one calendar month each."""
    d = start
    while d < end:
        nxt = date(d.year + d.month // 12, d.month % 12 + 1, 1)
        yield d, min(nxt, end)
        d = nxt


def backfill(words, start, end, folder="archive"):
    os.makedirs(folder, exist_ok=True)
    for since, until in months(start, end):
        path = f"{folder}/{since:%Y-%m}.jsonl"
        if os.path.exists(path):
            continue  # this month is already saved
        body = {"query": f"{words} since:{since} until:{until}",
                "order": "latest"}
        rows = []
        while True:
            r = requests.post(URL, headers=HEADERS, json=body)
            if r.status_code == 429:
                time.sleep(1)  # over 20 requests a second
                continue
            r.raise_for_status()
            page = r.json()
            rows += page.get("tweets", [])
            if not page.get("next_cursor"):
                break
            body["next_cursor"] = page["next_cursor"]
        with open(path, "w", encoding="utf-8") as f:
            for t in rows:
                f.write(json.dumps(t) + "\n")
        print(since, len(rows), "tweets")


backfill('"rainfall survey" lang:en', date(2015, 1, 1), date(2021, 1, 1))

热门话题,比如某个 cashtag 或某件世界大事,最好按天或按小时切分;冷门的话题标签,一个月就够了。如果需要比一天更细的窗口,X 的运算符也接受 Unix 秒数:since_time:1397692800 until_time:1397779200 就是 UTC 的 2014 年 4 月 17 日。

#回填历史数据要花多少钱

在 Sorsa API 上回填历史数据,按搜索每 1,000 条推文 $0.07 起,按推文 ID 获取每 1,000 条 $0.014 起。所以 100 万条历史推文 $70 起,如果你已经有 ID,则 $14 起。同样的 100 万条帖子,官方 X API 要收 $5,000。

历史推文

你的起点

100 万条历史推文 通过搜索找到,附带作者

$5,000

官方 X API

每条帖子 $0.005

11 月 22 日起附带作者,最高 $15,000

低至 $70

Sorsa API

低至每 1,000 条结果 $0.07

含作者

约 42 分钟 在 Sorsa API 上,按每秒 20 次请求计。 官方 X API 每月 300 万条帖子的上限,足够在一个计费周期内完成这项任务。

选择规模和起点,对比两种 API,并查看 Sorsa API 按每秒 20 次请求需要多久。

在任何规模下,按搜索回填的成本约为官方 X API 价格的 1/70,按 ID 回填约为 1/350。

历史推文数量Sorsa API,按搜索Sorsa API,按推文 ID官方 X API,仅帖子官方 X 按 300 万上限需要的计费周期
10 万$7 起$1.40 起$5001
100 万$70 起$14 起$5,0001
1,000 万$700 起$140 起$50,0004
1 亿$7,000 起$1,400 起$500,00034,或 Enterprise
  • 10 万

    Sorsa API,按搜索
    $7 起
    Sorsa API,按推文 ID
    $1.40 起
    官方 X API,仅帖子
    $500
    官方 X 按 300 万上限需要的计费周期
    1
  • 100 万

    Sorsa API,按搜索
    $70 起
    Sorsa API,按推文 ID
    $14 起
    官方 X API,仅帖子
    $5,000
    官方 X 按 300 万上限需要的计费周期
    1
  • 1,000 万

    Sorsa API,按搜索
    $700 起
    Sorsa API,按推文 ID
    $140 起
    官方 X API,仅帖子
    $50,000
    官方 X 按 300 万上限需要的计费周期
    4
  • 1 亿

    Sorsa API,按搜索
    $7,000 起
    Sorsa API,按推文 ID
    $1,400 起
    官方 X API,仅帖子
    $500,000
    官方 X 按 300 万上限需要的计费周期
    34,或 Enterprise

带“起”的价格用的是 Sorsa API 每次请求的最低费率;在 Pro 套餐上,搜索结果约为每 1,000 条 $0.10,按 ID 获取的推文约为 $0.02。失败的请求从不计费,每条推文里的作者资料也不另收费。

须知

从 2026 年 11 月 22 日起,官方 X API 会把扩展返回的每个对象,按其标准费率计费,这是 X 开发者团队在 10 月 23 日宣布(在新标签页打开)的。届时带作者一起读取的帖子,从 $0.005 涨到 $0.015。历史数据集几乎总是需要作者,所以在那边请按每 1,000 条帖子最高 $15.00 来预算。

官方 X API 的按量付费,还在每个计费周期读取 300 万条帖子时封顶。一次 1,000 万条推文的回填需要四个计费周期,而突破上限的唯一办法,是每月约 $42,000 起的 Enterprise 合同。官方的其他所有费率,都在我们的 X API 价格详解里。

#官方 X API 上的历史推文

官方 X API 通过全量归档搜索 GET /2/tweets/search/all 提供历史推文,它可以回溯到 2006 年 3 月,每次请求最多返回 500 条帖子。根据 X 的搜索文档(在新标签页打开),它面向按量付费客户和 Enterprise 客户开放。第一次调用之前,你需要一个获批的开发者账号、开发者控制台里的一个项目和一个应用,以及应用的密钥和令牌。每次读取都从你预先购买的额度里扣费,按 X 的价目表(在新标签页打开)是每条帖子 $0.005。日期以 ISO 8601 时间戳的形式放进 start_time 和 end_time。

按回填所需的条件衡量,Sorsa API 在价格、作者数据、数据量和配置上都占优,而且同样可以回溯到 2006 年 3 月。

API每 1,000 条推文的价格作者资料每月数据量配置
Sorsa API搜索 $0.07 起,按 ID $0.014 起每条推文都带,不另收费帖子没有上限,每秒 20 次请求一个 API 密钥
官方 X API$5.002026 年 11 月 22 日起,每 1,000 个作者 $10.00300 万条帖子,超出后转 Enterprise开发者账号、应用、OAuth 令牌、预付额度
  • Sorsa API

    每 1,000 条推文的价格
    搜索 $0.07 起,按 ID $0.014 起
    作者资料
    每条推文都带,不另收费
    每月数据量
    帖子没有上限,每秒 20 次请求
    配置
    一个 API 密钥
  • 官方 X API

    每 1,000 条推文的价格
    $5.00
    作者资料
    2026 年 11 月 22 日起,每 1,000 个作者 $10.00
    每月数据量
    300 万条帖子,超出后转 Enterprise
    配置
    开发者账号、应用、OAuth 令牌、预付额度

写入是官方 X API 仍然有用的地方:Sorsa API 从设计上就是只读,所以它从不发帖,也从不碰你的 X 账号。要发布内容,就搭配官方 X API;要读取,一个密钥就够了,没有开发者账号也能用的 Twitter API这篇指南对此有详细解释。

#谁能搜索 Twitter 归档,2006 年到 2026 年

在 Twitter 的大部分历史里,完整归档都锁在企业合同后面。研究人员曾有大约两年的免费访问,而自 2026 年 2 月起,任何开发者都可以向 X 按帖子购买。

二十年的归档访问,六个日期。研究人员的免费访问从 2021 年持续到 2023 年。

2021 年 1 月 26 日开通的 Academic Research 通道,让获批的研究人员可以免费使用全量归档搜索。2023 年 3 月 30 日,Twitter 宣布推出付费层级(在新标签页打开)时,旧的访问级别随之下线。学术用户被引导到通用套餐,而公司表示在寻找“继续服务这一群体的新方式”。学术访问在那年夏天失效,此后没有再出现过学术层级。研究人员可以用机构邮箱申请 Sorsa API 的学术研究访问权限。每次授权都根据研究的需要量身定制,从所需数量的请求到大幅折扣都有。

#单个账号的历史,或已发布的推文 ID 列表

要拉取某个账号发过的全部内容,就用它的 username、user_id 或个人主页链接调用 POST /user-tweets(在新标签页打开),再用 next_cursor 从最新的帖子翻到最早的。如果只要其中某几年,就改用 from: 加用户名,配合 since: 和 until: 来搜索。下载某个用户的全部推文这篇指南,一步步讲了如何导出为 CSV。

补全(rehydration)指的是,根据一份推文 ID 列表,把背后完整的推文取回来,大多数研究数据集就是以这种形式共享的。POST /tweet-info-bulk(在新标签页打开)每次请求最多接收 100 个 ID 或链接,并连同作者一起返回每条推文,每 1,000 条 $0.014 起,所以一份 100 万个 ID 的数据集 $14 起。发布之后被删除或被保护的推文,其 ID 会返回缺失,所以补全后的数据集总会比原来的略小。把剩下的内容变成训练数据,在如何构建用于机器学习的 Twitter 数据集里有介绍。

#用 100 次免费请求开始你的回填

要获取 Twitter 历史数据,从 Sorsa API 开始:一个 API 密钥触达回溯到 2006 年的每一条公开推文,所有套餐统一每秒 20 次请求。搜索每 1,000 条推文 $0.07 起,按 ID 查询每 1,000 条 $0.014 起。100 次免费请求能从任意日期窗口取回约 2,000 条推文,无需绑卡,也不会过期。先拉取你的话题的一个月,核对一遍,再规划完整的时间范围。

#常见问题

获取 Twitter 历史数据,最好的 API 是什么?

获取 Twitter 历史数据,用 Sorsa API:它能搜索回溯到 2006 年的每一条公开推文,每 1,000 条结果 $0.07 起,而官方 X API 是 $5.00。它支持 X 自己的搜索运算符,每条推文里都带着作者,不另收费。它没有每月 300 万条的上限,不需要开发者账号,所有套餐统一每秒 20 次请求。

有没有免费获取历史推文的办法?

有,适合小任务。X 的高级搜索会向已登录用户一屏一屏地显示旧推文。免费的按日期搜索推文工具可以列出某个账号在某一天发的内容。若要能导出的数据,Sorsa API 的 100 次免费请求,按搜索可取回约 2,000 条历史推文,按 ID 可取回 1 万条,无需绑卡。

能从 Twitter 归档里拿到已删除的推文吗?

不能。作者删除的推文会从 X 的搜索索引里消失,所以没有任何 API 能返回它:Sorsa API 不行,官方 X API 也不行。受保护账号或被封禁账号的帖子,同样拿不到。已删除的推文只可能保存在有人在它被删除前存下完整正文的地方,比如网页存档快照。

since: 和 until: 在 Twitter 搜索里是怎么工作的?

since:2014-04-01 返回从该日期起的推文,until:2014-05-01 在该日期之前停止,都按 UTC 计算,所以这一对正好覆盖 2014 年 4 月全月。可以把它们与关键词、from: 或 lang: 一起放进同一个查询。需要以小时为单位的窗口时,since_time: 和 until_time: 接受 Unix 秒数。Sorsa API 的 POST /search-tweets 支持这四个运算符。

能下载整个 Twitter 归档吗?

不能。没有人把全部公开推文的归档作为一次下载出售,X 只允许你在“设置和隐私”里下载你自己账号的归档。研究人员只能取回自己需要的那一部分。Sorsa API 可以按日期搜索回溯到 2006 年的任意关键词、话题标签或账号,每 1,000 条推文 $0.07 起,并能以每 1,000 条 $0.014 起的价格重建已发布的 ID 列表。

#我们如何核实

2026 年 11 月 2 日,我们读了 X 的按量付费价目表、它的搜索文档、它 2026 年 10 月 23 日关于计费扩展的通知,以及它 2023 年 3 月 30 日关于付费层级的公告。本页上官方 X API 的所有价格、限制和日期,都来自这些内容。同一天,我们把每个 Sorsa API 接口、参数和页面大小,与我们的实时接口文档和搜索运算符文档做了核对。请求和响应依据该文档、用演示账号构造,成本和耗时则是按已公布费率算出的。

Sorsa API 团队撰写。 我们开发和运营 Sorsa API,这是只读的 Twitter/X API 与爬虫,2022 年起运行于生产环境(前身为 TweetScout API),累计处理请求超 60 亿次。 关于 Sorsa API

更新内容
  • 从头重写。官方 X API 的价格、300 万上限,以及 2026 年 11 月 22 日起的作者计费,已在 X 自己的页面上重新核对。新增:获取历史推文的三条路线、按月回填的 Python 和 Node.js 脚本、成本与耗时计算器、历史推文如今返回什么,以及带日期的归档访问时间线。
  • 首次发布。