怎么找回很久以前的推文 —— 哪些方法真有用,哪些没用

18 min readSocialAPI 工程团队

怎么找回很久以前的推文 —— 哪些方法真有用,哪些没用

你记得那条推文。大概说了什么、大概什么时候、发的人是谁很确定。

你去搜,搜不到。你去他主页往下翻,翻了十分钟到六周前,放弃了。

这是一个已知且让人烦躁的缺口。X 的搜索索引严重偏向近期内容,而翻主页越往前越慢。两者都不是为"帮我找 2023 年的某条推文"设计的。

下面是真正有用的几种方法,按成功率排序。


方法一:你自己的存档(如果是你自己的账号)

如果那些推文是你自己发的,这就是答案 —— 而且几乎没人用。

X 会给你一份完整的存档,包含你发过的一切 —— 每条推文、每条回复、每条私信,一直回溯到你注册那天。不是抽样,是全部。

设置 → 你的账号 → 下载你的数据存档

等几小时到一两天,你会拿到一个 ZIP。里面有一个可浏览的 HTML,以及更有用的原始 JSON。

为什么它胜过其它所有方法: 它是完整的。没有索引缺口,没有限流,不用翻页。它是关于你自己账号的真相。

它唯一的局限: 它是快照。今天申请就只有到今天为止的内容;明天发的推文需要重新申请一次。

★如果这篇你只记住一件事:现在就去申请你的存档,在你需要它之前。★ 对于不属于你的账号,对应的动作是现在就开始捕获它们 —— 同样在你需要之前。


方法二:带时间范围的搜索

找别人的推文,先试这个。

from:username since:2023-01-01 until:2023-06-30

记得关键词的话就加上:

from:username "conference" since:2023-01-01 until:2023-12-31

效果好坏完全取决于内容有多老。 最近几个月很可靠;一年前时好时坏;好几年前的话,你搜的那个索引里往往根本就没有。

⚠️ 要把窗口切窄,而不是拉宽。 一个六个月的区间,返回的结果常常少于分三次跑的两个月区间 —— 因为每条查询在区间穷尽之前就先撞到了结果上限。把时间段切块分别跑,是这里最有效的一招。

如果你要连着跑很多个这样的时间窗,这正是接口比浏览器标签页更合适的场景


方法三:直接读主页时间线

搜索和主页浏览走的是不同的路径,而主页路径对老内容往往更好

用程序读时间线比手动翻能走得更远 —— 你是用游标往回翻页,而不是等界面加载更多。

import requests

BASE = "https://api.socialapi.tech"
KEY  = "your_api_key"

def get_timeline(username, pages=10):
    """往回翻某个用户的时间线。"""
    all_tweets, cursor = [], None

    for _ in range(pages):
        params = {"username": username, "limit": 100}
        if cursor:
            params["cursor"] = cursor

        r = requests.get(
            f"{BASE}/v1/user/last_tweets",
            params=params,
            headers={"X-API-Key": KEY},
            timeout=60,
        )
        r.raise_for_status()
        body = r.json()

        batch = body["data"]
        if not batch:
            break

        all_tweets.extend(batch)
        cursor = body.get("meta", {}).get("next_cursor")
        if not cursor:
            break

    return all_tweets

tweets = get_timeline("nasa", pages=10)
print(f"{len(tweets)} 条, 最旧一条: {tweets[-1]['created_at']}")

能期待什么: 单页返回约 100 条。对一个每天发几条的账号来说,那是两周左右。十页能回溯几个月。发得越勤的账号,每页覆盖的时间跨度越短。

这有上限 —— 不可能无限往回翻 —— 但对同一个账号,它比搜索能走得更远。


方法四:第三方存档

对于有历史意义的账号,往往已经有人做过存档了。政治人物、知名人士、各类机构账号都有公开存档存在。

它们是唯一能可靠拿到真正老内容的途径包括已删除的 —— 因为它们在当时就把内容捕获下来了。

它们的局限是覆盖面:只有那些被人认为值得存档的账号才有,而那是 X 上极小的一部分。


哪些方法没用

直说清楚,省得你浪费时间:

已删除的推文。 一旦删除,它就从 X 上彻底消失了 —— 搜索、主页、接口,全都没有。留存下来的是别人捕获的副本:一条引用推、一张截图、一份第三方存档。从 X 本身没有任何办法找回已删除的推文,任何声称能做到的工具,给你看的都是从别处来的缓存副本。

被封禁的账号。 账号被封,推文跟着一起没。和删除是同一种情况。

受保护的账号。 如果发布时就是受保护的,你当时看不到,之后也不会追溯性地变得能看。

Google。 有人建议用 site:twitter.com 搜。偶尔能碰上,但 Google 对 X 的覆盖很薄,而且越来越薄。值得花三十秒试试,不值得围绕它做计划。


可靠的答案:从现在开始往前捕获

上面每一种方法,本质都是在试图重建一段当初没保存的历史。它们全都有缺口,因为底层索引本身就有缺口。

如果你需要某些账号的可靠历史,可行的做法是别再重建,开始捕获。按计划轮询你关心的账号,把返回的内容存下来,三个月后你就有了三个月完整的历史 —— 包括那些后来被删掉的推文

import json, pathlib

def capture(username):
    """把新推文追加到本地档案。每天跑一次。"""
    archive = pathlib.Path(f"{username}_archive.jsonl")

    seen = set()
    if archive.exists():
        with archive.open() as f:
            seen = {json.loads(line)["id"] for line in f}

    fresh = [t for t in get_timeline(username, pages=2) if t["id"] not in seen]

    with archive.open("a") as f:
        for tweet in fresh:
            f.write(json.dumps(tweet) + "\n")

    return len(fresh)

每天跑一次,你的档案就在无缺口地增长。日常跑两页对大多数账号足够 —— 你只需要回溯到昨天。

值得记住的那个不对称:捕获未来既便宜又完整;重建过去既昂贵又满是窟窿。★ 开始的最佳时机是你第一次想要这份数据的时候,第二好的时机是现在。


大家会问的问题

怎么找某人很久以前的推文?from:username since: until: 搜。搜不到就用程序往回翻他的时间线,通常能走得更远。

怎么找我自己的老推文? 从设置里下载你的数据存档。它是完整的,其它方法都不是。

能搜自己的推特历史吗? 能,from:你的用户名 加关键词。真正老的内容,还是下载的存档更可靠。

推特搜索能回溯多久? 名义上到最早,实际上走不了多远。最近几个月可靠,几年前的查询顶多返回部分结果。

能恢复已删除的推文吗? 从 X 不能。删除会让它从 X 的每一个入口消失。只有外部副本 —— 引用、截图、第三方存档 —— 能留下来。

怎么看某人的第一条推文? 主页上有"加入时间";要拿到真正的第一条,得翻到他时间线的最末端 —— 只对发推不多的账号可行。

推特存档是什么? 两个不同的东西:从设置导出的你自己的数据 ZIP,以及第三方对知名账号做的存档。前者对你是完整的,后者对被存档的人是完整的。

下载存档要等多久? 通常几小时,有时一两天。准备好了 X 会发邮件通知你。

存档文件里有什么? 你的推文、回复、私信、点赞和账号历史 —— 有可浏览的 HTML,也有原始 JSON。要做处理的话,JSON 才是有用的那部分。

怎么清空推特搜索历史? 那说的是你自己搜索框的历史记录,不是推文 —— 点搜索栏清除最近搜索即可。和找老推文无关。

能搜特定某一天的推文吗? since:2023-05-01 until:2023-05-02 就是单独一天,前提是索引里还留着。

我确定存在的一条推文为什么搜不到? 最可能是索引没覆盖到 —— 老内容会逐渐稀疏。也可能是:它被删了、账号受保护,或者账号被封了。

能存档别人的推文吗? 能,靠你自己持续捕获。但你不能追溯性地存档你当初没捕获的东西。

怎么下载一个账号的全部推文? 你自己的:用存档导出。别人的:翻他的时间线并把结果存下来 —— 后者受限于时间线能回溯多远。

能搜被引用过的推文吗? 能,而且这是找已删除内容的一个实用技巧 —— 引用推常常把原文保留了下来,即使原推已经没了。

接口能给我完整历史吗? 没有任何接口能给完整历史,因为 X 自己的索引就没有。往前是完整的,往后是残缺的。

一次请求能拿多少条推文? 每页 100 条左右。用游标往回翻更多。

长期留存记录最好的办法是什么? 按计划捕获并自己存下来。任何依赖"X 还在提供那条推文"的方案,本质上都是临时的。

不登录能找老推文吗? 有时能,在网页端,而且限制很多。不是能依赖的做法。

怎么找到一个账号的第一条推文? 一直翻到时间线末尾。小账号便宜,大账号昂贵★ —— 成本是页数,不是难度。

怎么看某人的推特历史? 按顺序翻他的时间线。"历史"是你拼装出来的★ —— 没有任何端点会把它作为一个整体交给你。

怎么看我自己的推特历史? 要完整就申请官方账号存档,只要公开可见的部分就翻自己的时间线。

推特有观看历史吗? 没有。观看不以任何可取回的形式被记录★ —— 管辖这件事的那条边界

怎么搜索一份存档? 只能在捕获过那些帖子的存档内部搜。平台搜索不是存档★,这正是老帖子变得更难找、而不是找不到的原因。

能找到某个特定的人最早的帖子吗? 能 —— 一直翻到末尾。约束是要翻多少页,不是能不能做到。

为什么会存在公众人物的推文存档? 因为有人持续捕获了它们。那是唯一的机制★ —— 没有人是事后重建出来的

怎么搜索一份推特存档? 只能在捕获过那些帖子的存档内部搜。 ★平台搜索不是存档★ —— 这个区别比听起来更要紧。

怎么查看我的推特历史? 要完整就申请官方账号存档,只要公开部分就翻自己的时间线。

推特有观看历史吗? ★没有。★ 观看从不以可取回的形式被记录 —— 那条规则

怎么看我的全部推特历史? 官方存档是唯一的完整副本 —— ★在删除任何东西之前先申请★。

能拿到粉丝数的历史吗? ★只有你记录过才行。★ 没有任何历史序列会被提供 —— 怎么自己建一个

有粉丝历史工具吗? 任何存每日快照的工具都是。 ★它们没法给你"你开始之前"的历史。★

我的存档能回溯多远? 到账号的最开始 —— ★这正是它和搜索不同的地方★。

存档要等多久? 几小时到一两天,以可下载文件的形式给你。

能拿到别人的存档吗? ★不能 —— 存档只对账号所有者开放。★ 对其他账号,翻他的时间线。

存档里包含已删除的帖子吗? 只有它们在生成那一刻还存在才包含 —— 删除移除了什么

能在下载的存档里搜索吗? 能 —— 它是一个本地文件,★这让它比平台好搜得多★。

存档是什么格式? 一个可浏览的包,里面含底层数据。

能自动化归档吗? ★能 —— 定时翻页★ —— 往前捕获的模式胜过任何往回重建。

帖子还在的话为什么还要归档? ★因为删除不可逆而且不预告★ —— 你没法追溯地去捕获。


如果你要搭一套存档

上面那个捕获脚本就是它的形状。让它长期能用的是那些无聊的部分:不会截断的翻页、重启后依然有效的去重,以及能把限流和瞬时失败区分开的重试。

这些正是我们的 API 在处理的 —— 基于游标的翻页,每条推文都带完整互动数据,固定按次价格,没有属于你的限流要管。

有两种情况我们不收钱:请求还没发出去就被我们拒绝的(比如参数写错),以及我方原因导致的错误。

延伸阅读:包含时间范围在内的高级搜索操作符 · 实时监控账号 · X 接口报限流错误时该怎么办