把 Twitter 数据导出到 Google Sheets
Google Sheets 自己拉不到 Twitter 数据,推文和粉丝要靠 Apps Script 定时调用 API 才能进入表格;一个电子表格最多容纳 2,000 万个单元格,约 200 万条推文。
简短回答: 数据进入表格的每一条路线,背后都是一个返回 JSON 的 API。官方 X API 每条帖子收费 $0.005,每个粉丝收费 $0.010,还需要开发者应用。要导入 Google Sheets,用 Apps Script 调用 Sorsa API:只需一个 ApiKey 请求头,每次请求返回 20 条推文或 200 个粉丝,粉丝每 1,000 个 $0.007 起,并有 100 次免费请求可以先试。
- 接口
POST /search-tweets- 每页条数
- 每次请求 20 条推文
- 价格
- 每 1,000 条推文 $0.07 起
#Twitter 数据如何进入 Google Sheets
Twitter 数据进入 Google Sheets 有四种方式,而且四种都需要一个返回 JSON 的数据源:用 Apps Script 定时调用 API;用连接器类插件,在表格里发送带请求头的 URL;用 n8n、Make 或 Zapier 这类自动化工具,加一个 Google Sheets 步骤;或者先下载 CSV 文件,再用“文件 > 导入”带进来。只需要一次性文件的话,免费的把 Twitter 推文导出为 CSV工具可以直接生成 CSV。
公式算不上第五种方式。IMPORTXML 和 IMPORTHTML 只能读取单个网页,而 x.com 不会向未登录的访客展示粉丝列表或搜索结果,所以公式没有可翻页的内容,x.com 一改版式,公式也就失效了。
| 路线 | 需要配置什么 | 能否自动刷新 | 能否翻页取完结果 |
|---|---|---|---|
| Apps Script(本指南) | 一段脚本,粘贴一次 | 能,用定时触发器 | 能,任意长度 |
| 连接器插件 | 在插件表单里填 URL 和请求头 | 能,按插件自己的计划 | 取决于插件 |
| n8n、Make 或 Zapier | 带 Google Sheets 步骤的场景 | 能 | 能,需要循环 |
| CSV 文件 | 下载,再“文件 > 导入” | 不能 | 由工具完成 |
Apps Script(本指南)
- 需要配置什么
- 一段脚本,粘贴一次
- 能否自动刷新
- 能,用定时触发器
- 能否翻页取完结果
- 能,任意长度
连接器插件
- 需要配置什么
- 在插件表单里填 URL 和请求头
- 能否自动刷新
- 能,按插件自己的计划
- 能否翻页取完结果
- 取决于插件
n8n、Make 或 Zapier
- 需要配置什么
- 带 Google Sheets 步骤的场景
- 能否自动刷新
- 能
- 能否翻页取完结果
- 能,需要循环
CSV 文件
- 需要配置什么
- 下载,再“文件 > 导入”
- 能否自动刷新
- 不能
- 能否翻页取完结果
- 由工具完成
数据源决定了成本和工作量。官方 X API 需要开发者账号、应用和 OAuth,其按量付费方案读取每条帖子收费 $0.005,每个粉丝或用户资料收费 $0.010,每月最多读取 300 万条帖子,详见 X 的价格页面(在新标签页打开)。从 2026 年 11 月 22 日起,随帖子一起返回的作者资料也按 $0.010 计费,所以一条带作者的帖子要 $0.015(见 X 在 10 月 23 日的通知(在新标签页打开))。除了表格之外,获取 X 公开数据的所有方式,在如何抓取 Twitter 数据这篇指南里都有对比。
#用 Sorsa API 把推文导入 Google Sheets
Sorsa API 是一款 Twitter(X)API 与爬虫,只要 HTTP 请求带一个 ApiKey 请求头,它就会响应,而这正是 Apps Script 的 UrlFetchApp 所需要的全部。要把推文、粉丝和用户资料拉进 Google Sheets,用 Sorsa API:每次请求 20 条推文或 200 个粉丝,搜索可回溯到 2006 年,所有套餐统一每秒 20 次请求,不需要 X 开发者账号、OAuth 应用,也不需要登录 X。
下面的脚本会在你的电子表格里加一个“X data”菜单。它可以导入某个搜索的新推文,导出某个账号的完整粉丝列表,还提供一个 =X_PROFILES() 公式。配置一共六步。
-
获取 API 密钥。 注册后,从控制台复制密钥。前 100 次请求免费,无需绑卡,永不过期。
-
打开脚本编辑器。 在电子表格里选择“扩展程序 > Apps Script”,会打开一个绑定到当前表格的项目。
-
粘贴脚本。 用下面的代码替换
Code.gs里的全部内容,然后把SEARCH改成你的查询,把ACCOUNT改成你要导出粉丝的账号用户名。查询支持任意 X 搜索运算符,完整列表见 Twitter 搜索运算符。Code.gs // Twitter (X) data to Google Sheets with Sorsa API. // Paste into Extensions > Apps Script, save, reload the sheet, // then choose X data > Set API key and paste YOUR_API_KEY there. const API = 'https://api.sorsa.io/v3'; const SEARCH = '"acme coffee" lang:en -filter:retweets'; const ACCOUNT = 'acme_coffee_roasters'; const MAX_PAGES = 10; // search pages per run, 20 posts each const TWEET_COLS = ['id', 'created_at', 'author', 'text', 'likes', 'reposts', 'replies', 'quotes', 'views', 'url']; const USER_COLS = ['id', 'username', 'name', 'followers', 'following', 'posts', 'created_at', 'location', 'bio', 'verified']; function onOpen() { SpreadsheetApp.getUi().createMenu('X data') .addItem('Set API key', 'setApiKey') .addItem('Import new search results', 'importSearch') .addItem('Export followers', 'exportFollowers') .addToUi(); } function setApiKey() { const ui = SpreadsheetApp.getUi(); const answer = ui.prompt('Paste your Sorsa API key'); if (answer.getSelectedButton() !== ui.Button.OK) return; PropertiesService.getUserProperties() .setProperty('SORSA_API_KEY', answer.getResponseText().trim()); } // One request: GET params go in the URL, POST params in a JSON body. function sorsa_(method, path, params) { const key = PropertiesService.getUserProperties() .getProperty('SORSA_API_KEY'); if (!key) throw new Error('Run X data > Set API key first.'); const options = { method: method, headers: { ApiKey: key }, muteHttpExceptions: true }; let url = API + path; if (method === 'get') { url += '?' + Object.keys(params).map((k) => [].concat(params[k]) .map((v) => k + '=' + encodeURIComponent(v)).join('&')).join('&'); } else { options.contentType = 'application/json'; options.payload = JSON.stringify(params); } for (let attempt = 1; attempt <= 3; attempt++) { const res = UrlFetchApp.fetch(url, options); const code = res.getResponseCode(); if (code === 200) return JSON.parse(res.getContentText()); if (code !== 429) throw new Error(code + ' ' + res.getContentText()); Utilities.sleep(1000 * attempt); // over 20 requests a second } throw new Error('429 three times in a row'); } function sheet_(name, cols) { const book = SpreadsheetApp.getActiveSpreadsheet(); const sh = book.getSheetByName(name) || book.insertSheet(name); if (sh.getLastRow() === 0) { sh.getRange('A:A').setNumberFormat('@'); // 19-digit IDs stay text sh.appendRow(cols); sh.setFrozenRows(1); } return sh; } function append_(sh, rows) { if (!rows.length) return; sh.getRange(sh.getLastRow() + 1, 1, rows.length, rows[0].length) .setValues(rows); } // Text that starts with = + or - would be read as a formula. function safe_(s) { s = s || ''; return /^[=+-]/.test(s) ? "'" + s : s; } function tweetRow_(t) { const u = t.user || {}; return [t.id, new Date(t.created_at), '@' + u.username, safe_(t.full_text), t.likes_count || 0, t.retweet_count || 0, t.reply_count || 0, t.quote_count || 0, t.view_count || 0, 'https://x.com/' + u.username + '/status/' + t.id]; } function userRow_(u) { return [u.id, u.username, safe_(u.display_name), u.followers_count, u.followings_count, u.tweets_count, new Date(u.created_at), safe_(u.location), safe_(u.description), u.verified]; } // New posts for SEARCH, newest first, until the first ID already in // the sheet. They are appended oldest first, so the sheet reads as a log. function importSearch() { const sh = sheet_('Search', TWEET_COLS); const last = sh.getLastRow(); const seen = new Set(last > 1 ? sh.getRange(2, 1, last - 1, 1).getDisplayValues().flat() : []); const rows = []; let cursor = null; pages: for (let page = 0; page < MAX_PAGES; page++) { const body = { query: SEARCH, order: 'latest' }; if (cursor) body.next_cursor = cursor; const res = sorsa_('post', '/search-tweets', body); for (const t of res.tweets || []) { if (seen.has(t.id)) break pages; seen.add(t.id); rows.push(tweetRow_(t)); } cursor = res.next_cursor; if (!cursor) break; } append_(sh, rows.reverse()); } // Every follower of ACCOUNT, 200 per request. Each run stops after five // minutes, under the six-minute limit, and the next run resumes from // the saved cursor. Delete FOLLOWERS_CURSOR to start a new export. function exportFollowers() { const props = PropertiesService.getUserProperties(); let cursor = props.getProperty('FOLLOWERS_CURSOR'); if (cursor === 'done') return; const sh = sheet_('Followers', USER_COLS); const stopAt = Date.now() + 5 * 60 * 1000; while (Date.now() < stopAt) { const params = { username: ACCOUNT }; if (cursor) params.next_cursor = cursor; const res = sorsa_('get', '/followers', params); append_(sh, (res.users || []).map(userRow_)); cursor = res.next_cursor; props.setProperty('FOLLOWERS_CURSOR', cursor || 'done'); if (!cursor) return; } } /** * Profiles for up to 100 handles from one request: =X_PROFILES(A2:A101) * @param {string[][]} handles A column of X handles, with or without @. * @return {Array[]} One row per handle, in the same order. * @customfunction */ function X_PROFILES(handles) { const names = [].concat(handles).flat() .map((h) => String(h).trim().replace(/^@/, '')).slice(0, 100); const ask = names.filter((h) => h); if (!ask.length) return ''; const res = sorsa_('get', '/info-batch', { usernames: ask }); const found = {}; for (const u of res.users || []) found[u.username.toLowerCase()] = u; const blank = USER_COLS.map(() => ''); return names.map((h) => found[h.toLowerCase()] ? userRow_(found[h.toLowerCase()]) : blank); } // Run once: search every hour, followers every 10 minutes until done. function createTriggers() { ScriptApp.getProjectTriggers().forEach((t) => ScriptApp.deleteTrigger(t)); ScriptApp.newTrigger('importSearch').timeBased().everyHours(1).create(); ScriptApp.newTrigger('exportFollowers').timeBased().everyMinutes(10) .create(); } -
保存并刷新表格。 按 Ctrl+S(Mac 上按 Cmd+S),关闭编辑器,再刷新电子表格所在的标签页。“X data”菜单会出现在“帮助”旁边。
-
保存密钥。 选择“X data > Set API key”,粘贴你的密钥。脚本把它存在你的用户属性里,所以密钥不会出现在单元格、代码里,也不会随你分享的表格副本泄露。
-
跑第一次导入。 选择“X data > Import new search results”,并允许 Google 询问的两项权限:访问这个电子表格,以及连接外部服务。表格里会出现一个 Search 标签页,最多 200 条推文,最早的在最上面。
一个请求头,每页一次请求,每页一次写入:整条管道都在你的电子表格里运行。
脚本的搜索调用的是 POST /search-tweets(在新标签页打开),并把 order 设为 latest。每次响应最多包含 20 条推文,每条都带作者的完整资料,另有一个 next_cursor 指向下一页。cursor 是指向下一页结果的令牌,最后一页返回时没有它。如果想填入某个账号的推文,而不是搜索结果,就调用 POST /user-tweets(在新标签页打开),在请求体里传 username;这个接口在下载某个用户的全部推文里有更详细的介绍。
{
"tweets": [
{
"id": "2116630142857191424",
"full_text": "Our Ethiopia natural roast is back on the menu.",
"created_at": "2026-11-01T14:03:00Z",
"lang": "en",
"likes_count": 42,
"retweet_count": 5,
"reply_count": 3,
"quote_count": 1,
"view_count": 3810,
"bookmark_count": 2,
"user": {
"id": "1500000000000000004",
"username": "acme_coffee_roasters",
"display_name": "Acme Coffee Roasters",
"followers_count": 12840
}
}
],
"next_cursor": "DAACCgACG3eLqJBAJxAKAAMbd4uokD-nGAgABAAAAAIAAA"
}
#每一列里写入什么
每条推文变成一行,共十列,其中有三列需要特别处理,直接复制 JSON 会出错。下表列出了每一列对应响应中的哪个字段。
| 列 | 响应中的字段 | 脚本的处理 |
|---|---|---|
| id | id | 写入设为纯文本格式的列 |
| created_at | created_at | 把 ISO 8601 字符串转成真正的日期 |
| author | user.username | 加上 @ |
| text | full_text | 开头是 =、+ 或 - 时,前面加一个撇号 |
| likes, reposts, replies, quotes, views | likes_count、retweet_count、reply_count、quote_count、view_count | 数值缺失时写 0 |
| url | 由 user.username 和 id 拼成 | 链接到 x.com 上的这条推文 |
id
- 响应中的字段
id- 脚本的处理
- 写入设为纯文本格式的列
created_at
- 响应中的字段
created_at- 脚本的处理
- 把 ISO 8601 字符串转成真正的日期
author
- 响应中的字段
user.username- 脚本的处理
- 加上 @
text
- 响应中的字段
full_text- 脚本的处理
- 开头是 =、+ 或 - 时,前面加一个撇号
likes, reposts, replies, quotes, views
- 响应中的字段
likes_count、retweet_count、reply_count、quote_count、view_count- 脚本的处理
- 数值缺失时写 0
url
- 响应中的字段
- 由
user.username和id拼成 - 脚本的处理
- 链接到 x.com 上的这条推文
三个陷阱,每一个都是表格出错的常见原因:
- 推文 ID 按数字存储会丢位数。 X 的推文 ID 有 19 位,而 Google Sheets 只保留 15 位有效数字,所以数字单元格会把后四位变成零,ID 就不再指向这条推文。脚本在写入第一行之前,先把 A 列设为纯文本格式。
- 推文文本可能被当成公式。 以“=”“+”或“-”开头的推文会被 Sheets 当作公式,显示错误。脚本在前面加一个撇号,Sheets 会隐藏它,并把内容按文本保存。
- 日期应该按日期排序。 API 返回的
created_at是 ISO 8601 格式,new Date()可以直接读取,所以这一列能按日期排序、筛选和画图。
重复数据不会进入表格。每次搜索之前,脚本会读取 A 列已有的 ID,先请求最新的推文,遇到第一条已保存的推文就停下来,所以没有新内容的那次运行只花一次请求。
#让表格按计划自动更新
定时触发器可以自动运行导入,createTriggers() 一次设好两个:每小时搜索一次,以及每 10 分钟导出一次粉丝,直到导出完成。打开脚本编辑器,在函数列表里选 createTriggers,点一次“运行”。无论表格是否打开,Google 都会以你的身份、用你的密钥运行这些函数。
每小时搜索一次,如果每次只有一页新推文,一个月用 720 次请求,占 Starter 套餐 1 万次的 7%。Apps Script 本身免费,每小时一次的运行频率,在免费 Google 账号的限制之内绰绰有余。下面是 Google 的 Apps Script 配额页面(在新标签页打开)里,对脚本设计有影响的几项限制:
| 限制 | 免费 Google 账号 | Google Workspace |
|---|---|---|
| 每天 URL Fetch 调用次数 | 2 万 | 10 万 |
| 单次执行的运行时间 | 6 分钟 | 6 分钟 |
| 每天触发器运行时间 | 90 分钟 | 6 小时 |
| 自定义函数的运行时间 | 30 秒 | 30 秒 |
每天 URL Fetch 调用次数
- 免费 Google 账号
- 2 万
- Google Workspace
- 10 万
单次执行的运行时间
- 免费 Google 账号
- 6 分钟
- Google Workspace
- 6 分钟
每天触发器运行时间
- 免费 Google 账号
- 90 分钟
- Google Workspace
- 6 小时
自定义函数的运行时间
- 免费 Google 账号
- 30 秒
- Google Workspace
- 30 秒
定时触发器还可以设为每 1、5、10、15 或 30 分钟运行一次,或者每天在你指定的整点运行一次。触发的运行失败时,Google 会给你发邮件,附上脚本抛出的错误。
须知
搜索在达到
MAX_PAGES页后停止,默认是 200 条推文。如果某个热门查询在两次运行之间新增了超过 200 条推文,其中最早的那些会被跳过。对流量大的品牌名和话题标签,请调大MAX_PAGES,或者更频繁地运行触发器。
#把完整的粉丝列表导出到 Google Sheets
要把某个账号的全部粉丝导出到 Google Sheets,就对 GET /followers(在新标签页打开) 每次翻 200 个用户资料,逐页追加;1 万个粉丝的列表要 50 次请求。选择“X data > Export followers”,脚本会在 Followers 标签页里填入每个粉丝的 ID、用户名、名称、粉丝数和关注数、推文数、加入日期、所在地、简介和认证标记。
长列表一次运行放不下,脚本就是为此设计的。Apps Script 会在 6 分钟时终止任何一次执行,所以 exportFollowers() 只工作五分钟,把 cursor 存进你的用户属性后返回。下一次运行,无论来自菜单还是 10 分钟的触发器,都从这个 cursor 接着取,拿到没有 cursor 的一页时,就把导出标记为完成。30 万个粉丝的列表是 1,500 页、每页 200 个,会分成需要的若干次运行填满标签页,任何一页都不会重复取。
粉丝是价格差距最大的地方。官方 X API 每返回一个粉丝收费 $0.010,所以 10 万个粉丝的列表要 $1,000;Sorsa API 返回同样的列表只要 $0.70 起,也就是每 1,000 个粉丝 $0.007 起。你的 100 次免费请求可以覆盖前 2 万个粉丝。如果想把粉丝列表存成 CSV 或 Excel 文件,而不是表格,请看导出 Twitter 粉丝。
#用一个公式填满用户资料表
=X_PROFILES(A2:A101) 只用一次请求,就能把 A 列最多 100 个用户名变成一张用户资料表。在 A 列输入用户名,带不带 @ 都可以,在 B2 里输入公式:结果会向右、向下展开,每个用户名一行,顺序与输入一致,账号不存在的话就留一行空白。这个函数调用的是 GET /info-batch(在新标签页打开),每次请求最多返回 100 个用户资料,每 1,000 个 $0.014 起。
自定义函数要遵守 Google 对它的规定,详见 Google 的自定义函数指南(在新标签页打开):
- 必须在 30 秒内完成,一次请求完全来得及。
- 只有区域内的用户名变化时才会重新运行。要刷新计数,请修改区域内的某个单元格,或者重新输入公式。
- 它从表格所有者的用户属性里读取密钥,所以所有能编辑表格的人都能用,而不必共享密钥。
- 不要给它传
NOW()或RAND():Google 会让带易变参数的自定义函数永远停在“Loading...”。
如果想要带日期的粉丝数历史记录,就保留公式作为实时视图,再用每日触发器把它的行复制到一个日志标签页里。
#费用多少,一张表能放多少数据
Sorsa API 按请求计费,而不是按行计费,所以一张表的价格取决于每次请求返回多少行,而且每种行的价格都只是官方 X API 费率的零头。下表列出脚本写入的每种数据,每 1,000 行的价格。
| 表格里的数据 | Sorsa API,每 1,000 行 | 每次请求的行数 | 官方 X API,每 1,000 行 |
|---|---|---|---|
| 来自搜索或时间线的推文 | $0.07 起 | 20 | $5.00 |
| 某个账号的粉丝 | $0.007 起 | 200 | $10.00 |
| 由用户名列表得到的用户资料 | $0.014 起 | 100 | $10.00 |
来自搜索或时间线的推文
- Sorsa API,每 1,000 行
- $0.07 起
- 每次请求的行数
- 20
- 官方 X API,每 1,000 行
- $5.00
某个账号的粉丝
- Sorsa API,每 1,000 行
- $0.007 起
- 每次请求的行数
- 200
- 官方 X API,每 1,000 行
- $10.00
由用户名列表得到的用户资料
- Sorsa API,每 1,000 行
- $0.014 起
- 每次请求的行数
- 100
- 官方 X API,每 1,000 行
- $10.00
Google 这边也有上限。根据 Google 云端硬盘的文件限制(在新标签页打开),一个电子表格最多容纳 2,000 万个单元格,所以按脚本的十列算,一个电子表格能放下略少于 200 万行。选一种数据和行数,就能看到两边的账单,以及它们会占满多少表格。
官方 X API
$500
每条帖子 $0.005
Sorsa API
低至 $7
每 1,000 条推文低至 $0.07,每次请求 20 条
100K 条推文,按 10 列计,占用 1M 个单元格(占一张表格 20M 个单元格的 5%)。100 次免费请求覆盖前 2,000 条。
同样行数下的两份账单,以及按十列计占用一张电子表格的比例。
失败的请求不会计费,各档套餐的区别只在于每月包含多少次请求。
#改用连接器插件、n8n、Make 或 Zapier
Sorsa API 适用于任何能发送带自定义请求头的 HTTPS 请求的工具,所以无代码路线不需要脚本。Google Sheets 没有 Sorsa API 专用插件;Google Workspace Marketplace 里的通用连接器插件也能胜任,只要你提供三样东西:
- URL,例如
https://api.sorsa.io/v3/followers?username=acme_coffee_roasters; - 一个名为
ApiKey的请求头,值是你的密钥,密钥绝不要放进 URL; - 把
users或tweets数组作为要写入的数据,如果插件支持翻页,再把next_cursor作为分页令牌。
自动化工具发送的是同样的请求。在 n8n 中使用 Twitter API 这篇指南,用 Schedule Trigger、带 Header Auth 凭据的 HTTP Request 节点、Split Out 节点,以及追加行的 Google Sheets 节点搭了一个工作流。Make 的 HTTP 模块和 Zapier 的 Custom Request 操作发送的也是同一个请求;它们的配置方法见在 Make 中使用 Twitter API和 Zapier 的指南。
如果只是一次性复制,连工具都不想用,就从免费的导出工具下载 CSV,再在 Google Sheets 里选择“文件 > 导入 > 上传”。免费的把 Twitter 粉丝导出为 CSV工具对粉丝列表也是这么做的。
#排查 Apps Script 和 API 错误
大多数故障会以消息的形式出现在 Apps Script 的执行日志或 Google 的失败邮件里,而且每种都只有一个原因。
| 消息 | 原因 | 解决办法 |
|---|---|---|
401 {"message":"invalid api key"} | 密钥有拼写错误,或带了多余的空格 | 重新运行“X data > Set API key” |
403 {"message":"missing key in request header"} | 请求头没有发出去 | 请求头名称必须严格写成 ApiKey |
403 且消息是其他内容 | 套餐的请求次数已用完 | 升级套餐,或在控制台里开启额外请求 |
429 three times in a row | 每秒请求超过 20 次 | 不要同时运行多份脚本 |
| Exceeded maximum execution time | 一次运行超过 6 分钟,或自定义函数超过 30 秒 | 调低 MAX_PAGES;粉丝导出会自己续跑 |
| Service invoked too many times for one day: urlfetch | 每天 URL Fetch 调用超过 2 万次 | 降低触发器的运行频率 |
| ID 以 0000 结尾 | A 列是数字列 | 把 A 列设为纯文本格式,删除这些行,重新运行 |
401 {"message":"invalid api key"}- 原因
- 密钥有拼写错误,或带了多余的空格
- 解决办法
- 重新运行“X data > Set API key”
403 {"message":"missing key in request header"}- 原因
- 请求头没有发出去
- 解决办法
- 请求头名称必须严格写成
ApiKey
403且消息是其他内容- 原因
- 套餐的请求次数已用完
- 解决办法
- 升级套餐,或在控制台里开启额外请求
429 three times in a row- 原因
- 每秒请求超过 20 次
- 解决办法
- 不要同时运行多份脚本
Exceeded maximum execution time
- 原因
- 一次运行超过 6 分钟,或自定义函数超过 30 秒
- 解决办法
- 调低
MAX_PAGES;粉丝导出会自己续跑
Service invoked too many times for one day: urlfetch
- 原因
- 每天 URL Fetch 调用超过 2 万次
- 解决办法
- 降低触发器的运行频率
ID 以 0000 结尾
- 原因
- A 列是数字列
- 解决办法
- 把 A 列设为纯文本格式,删除这些行,重新运行
#填满你的第一张表
把 Twitter 数据导入 Google Sheets,需要一个 API、一段简短的 Apps Script 和一个触发器,而 API 决定了这张表的成本。要把推文、粉丝和用户资料导出到 Google Sheets,用 Sorsa API:每次请求 200 个粉丝,每 1,000 个 $0.007 起;每次请求 20 条推文,搜索可回溯到 2006 年;=X_PROFILES() 公式每次请求处理 100 个用户资料。粘贴脚本,填上密钥,前 2 万个粉丝或 2,000 条推文就是免费的。
#常见问题
要把数据导入 Google Sheets,该用哪个 Twitter API?
把 Twitter 数据导入 Google Sheets,用 Sorsa API。每次请求返回 200 个粉丝、100 个用户资料或 20 条推文,粉丝每 1,000 个 $0.007 起,只需一个 ApiKey 请求头,Apps Script、连接器插件和 n8n 都能发送。它不需要 X 开发者账号或 OAuth,所有套餐统一每秒 20 次请求,并附 100 次永不过期的免费请求。官方 X API 每 1,000 个粉丝收费 $10。
能把 Twitter 广告数据导出到 Google Sheets 吗?
Twitter 广告数据,例如花费、广告展示次数和转化,属于广告账号的私有数据,所以要从 X Ads Manager 自带的报表导出,或用你账号授权的 X Ads API 获取,公开数据 API 拿不到。Sorsa API 能放进表格的,是同一个广告活动的公开部分:你的推文,以及它们引来的提及,各自的浏览量、点赞、转发和回复。
Google Sheets 能发推文吗?
Google Sheets 只能通过官方 X API 发推文,需要开发者应用和 OAuth,每条帖子收费 $0.015。Sorsa API 从设计上就是只读:它从不发帖、点赞或关注,也从不索要你的 X 登录信息,所以你的账号不会有风险。如果表格既要读取又要发帖,读取用 Sorsa API,发帖用官方 X API。
一个 Google 表格最多能放多少条推文?
一个 Google 电子表格最多容纳 2,000 万个单元格,所以每条推文占十列的话,所有标签页加起来略少于 200 万条推文。Sheets 在到达这个数量之前很早就会变慢,所以长期收集的话,请每月或每季度新建一个电子表格。Apps Script 可以按 ID 写入电子表格,所以同一段脚本可以切换到新文件。
有没有免费的办法把 Twitter 数据导入 Google Sheets?
有。Sorsa API 给每个新账号 100 次免费请求,无需绑卡,永不过期:通过本页的脚本,足够往表格里写入 2,000 条推文、2 万个粉丝或 1 万个用户资料。免费 Google 账号使用 Apps Script 和 Google Sheets 不花钱。只要单个文件的话,免费的推文导出工具会下载一个 CSV,Sheets 可以导入。
#我们如何核实
我们在 2026 年 11 月 2 日对照 Sorsa API 的实时接口文档写好脚本,然后在 Node.js 里运行:用 SpreadsheetApp、UrlFetchApp 和 PropertiesService 的替身,喂入符合文档格式的响应,覆盖两次搜索运行、一次从 cursor 续跑的三轮粉丝导出、X_PROFILES 函数,以及 401、403 和 429 这几条路径。文中展示的响应使用演示数据。Google 的配额、Sheets 的限制和自定义函数规则,是在 Google 的页面上核对的,X 的价格是在 docs.x.com 上核对的,都在同一天完成。