评论卡片经过一份来源台账,连接到一张表和一份单独的导入核对记录。
核对样本和导入后的行。

顶层评论是直接写在帖子上的评论。它不是另一条评论下面的回复。在本文中,样本是你按书面规则保存的公开评论。它不是 Instagram 上的每一条评论。

导出是指你把已保存的行下载成一个文件。Actor 是一个托管程序,用来采集这些行。Task 是为该 Actor 保存的一套输入预设。一次运行是用一套输入做的一轮采集。Actor 保存来源行。计数和编码由你来做。

每一行保存了什么

这些字段规则已于 2026-10-13 对 Instagram Comments Scraper Actor 的公开版本 0.1.21 做过核对。一个字段是一行上的一个具名值。这个版本在每一行保存一条公开的顶层评论。

每一行都有 `postUrl`、`postId`、`postShortCode`、`commentId`、`text`、`createdAt`、`likesCount`、`repliesCount`、`ownerId`、`ownerUsername`、`ownerVerified` 和 `collectedAt`。

`postUrl` 是你输入的帖子链接。`postId` 是该帖子的来源标识。`postShortCode` 是该链接里的短代码。短代码是 `/p/`、`/reel/` 或 `/tv/` 后面的那一段。`commentId` 是一条评论的来源标识。`text` 是评论的文字。`createdAt` 是来源给出的评论时间。`likesCount` 是来源显示的点赞数。`repliesCount` 是来源显示的回复数。它不是回复正文。`ownerId` 是发表该评论的账号的来源标识。`ownerUsername` 是该账号的公开名称。`ownerVerified` 表示来源是否在该账号上显示了认证标记。`collectedAt` 是 Actor 保存该行的时间。

Null 表示该值不可用。空文本没有任何字符。空文本和 null 不是一回事。Zero 表示这个数是零。False 表示认证标记为否。要把 null、零和 false 保留为不同的值。不要把 null 变成零或 false。

这个版本不在每一行上放状态字段。它不保存 `parentId`。它不保存回复正文。它不保存帖子说明文字。它不保存粉丝数。它不保存机器人分数。机器人分数会猜测一个账号是否为自动账号。它不保存情感标签。情感会是诸如称赞或抱怨这样的标签。它不标记谁算作一个群体的正式成员。所有者 ID 可以是 null。

没有可供编码的回复行。`repliesCount` 为 null,并不是一条正文为空的回复。它也不是一种情感。

1. 采集之前先写下取样框

取样框是你选定的帖子清单,以及你保留评论所用的规则。运行 Actor 之前先写下取样框。

写下这些项目:

  • 已知的公开帖子链接。
  • 把这些帖子列入清单的规则。
  • 日期窗口,或者注明你不按日期筛选。
  • 你将从 `collectedAt` 抄下的采集时间。
  • 语言规则。
  • 你计数的对象:评论、账号或帖子。

日期窗口是你选择保留的第一天和最后一天。你计数的对象就是你的单位。一条评论、一个账号和一条帖子是不同的单位。采集时间要写成 `collectedAt`,而不是你开始编码的那一天。

先写帖子清单,再去读评论。这样你就不会因为某条帖子的评论符合你的想法而把它加进来。运行之前写好日期窗口,或者写明你不使用日期窗口。在同一份笔记里写明单位。后来的计数很容易混在一起。下面这个虚构文件说明了原因。Actor 不会添加语言字段。写一条你能够执行的语言规则。例如,保留每一条已保存的文本,并在新列里标出语言。如果你去掉某一行,写下原因。

使用一条你已经知道的公开链接。链接必须包含 `/p/`、`/reel/` 或 `/tv/`。个人主页链接是账号页面。Story 是一条存在时间很短的快拍。话题标签链接是标签页面。Search 和 Explore 是浏览页面。这些路径不受支持。只使用公开帖子。不要采集私密账号或隐藏评论。

这个样本可以描述你保存的公开评论文本。它不能代表所有 Instagram 用户。关于全体用户的论断需要另一份挑选人员的计划。本文不写那份计划。

如果你使用日期筛选,结束日期是包含在内的。包含在内是指第一天或最后一天的评论可以留下。日期筛选打开时,没有 `createdAt` 的评论会被跳过。除非你去掉结果上限,否则日期筛选对每条帖子最多查看 250 条公开评论。从最早开始使用同一个查看上限。去掉结果上限仍然不会采集完整的公开信息流。如果你使用日期或从最早开始,把这个上限写进笔记。

2. 用上限 3 检查一条帖子

试运行是一次非常小的首次运行。你用它检查文件的形态。从一条已知的公开帖子和上限 3 开始。上限是你要求从一条帖子保存的评论的最高数量。上限是最大值,不是承诺的条数。

已保存的导出为 CSV 的 Task 已于 2026-10-13 核对。它保存的输入是:

json
{
  "postUrls": ["https://www.instagram.com/reel/DZu6dkVyImf/"],
  "maxCommentsPerPost": 250,
  "commentSortMode": "default",
  "collectAllAvailable": false
}
2. 用上限 3 检查一条帖子

那个 Reel 是起始输入。起始输入不是你的研究。一次运行不会替你做编码。把这个 Reel 换成你自己的公开帖子链接。

试运行使用这个形态:

json
{
  "postUrls": ["https://www.instagram.com/p/YOURPUBLICPOST/"],
  "maxCommentsPerPost": 3,
  "commentSortMode": "default",
  "collectAllAvailable": false
}
2. 用上限 3 检查一条帖子

`YOURPUBLICPOST` 是占位符。占位符是必须替换的替身。不要把这几个字母当作一条真实帖子去运行。

`commentSortMode` 设为 `default` 时,会保留该次请求的来源顺序。默认顺序并不保证是最新评论。也不保证是最早评论。也不是从全体用户中随机抽取。如果你后来选择最新或最早,这个选择只给该次运行已采集的评论排序。它本身不会越过第 1 步所说的查看上限。

`collectAllAvailable` 设为 false 时,会保留你的数字上限。如果你把它设为 true,数字上限会被去掉。运行仍可能在公开信息流结束、时间用完或来源失败时停止。在这些情况下停止,并不能说明已经覆盖每一条公开评论,也不能说明已经覆盖每一个 Instagram 用户。试运行请保持 `collectAllAvailable` 为 false。

一条帖子能让第一次检查保持很小。如果两条帖子同时失败,原因更难看清。上限 3 让你能用眼睛读完每一条已保存的行。Task 里的值 250 只是一个已保存的最大值。它不是对 250 条评论的承诺。较早的公开问题可能把 100 条评论说成工具上限。那个旧数字不是当前 Actor 的上限。你写下的上限才是你设置的最大值。把上限设得更高,仍然不表示已经采集到每一条评论。

运行之后,把 `postShortCode` 和你的 URL 对比。然后阅读 OUTPUT。OUTPUT 是与这些行一起保存的运行报告。先读顶部的 `requestedTargets`、`savedRows` 和 `cappedTargets`。对每个目标,读取 `resultState`、`sampleHealth` 和 `stopReason`。

一次已核对的运行为所请求的短代码保存了 3 行。这些行有评论 ID、文本、作者 ID 和日期。OUTPUT 显示为已达上限,停止原因是 `max_comments_reached`,`savedRows` 为 3。`repliesCount` 为 null。那次运行显示的是该来源上的字段形态。它没有显示该帖子的全部评论。它没有证明哪条评论最早。它没有列出回复正文或其他帖子。那次运行里作者 ID 是有的。后来的帖子仍然可能返回 null 所有者 ID。

是上限让那次运行停止的。达到上限的结果并不表示该帖子只有 3 条评论。只有这次形态检查通过之后,才选择你的研究上限。在你理解其他停止原因之前,保持 `collectAllAvailable` 为 false。

如果试运行没有返回任何行,不要写成该帖子没有评论。来源可见性可能失败。作决定之前先读 `resultState`、`sampleHealth` 和 `stopReason`。空行和已编码的情感不是一回事。

3. 保留原始 JSON

JSON 是一种文本格式,可以保留嵌套值和 null 这个词。JSONL 是指每一行有一个 JSON 对象。数据集是一次运行保存下来的那一组行。你可以按 Apify 数据集指南 中的说明导出它。

先保存原始 JSON 或 JSONL,以及 OUTPUT 报告。在那之后,再把 CSV 或 Excel 文件做成工作副本。CSV 是用逗号分隔各列的文本表。同时保存你使用的输入。保存帖子链接、上限、排序、`collectAllAvailable` 以及任何日期。

评论行没有用于整个数据集的状态字段。Excel 不会把 OUTPUT 放进评论单元格里。如果你只保留工作文件,就可能丢失生成它的那些规则。

保留 JSON,是因为 CSV 可能掩盖 null 和空值的差别。下面这两个虚构值不是研究计数:

json
{"text": null, "likesCount": null, "ownerVerified": null}
3. 保留原始 JSON
json
{"text": "", "likesCount": 0, "ownerVerified": false}
3. 保留原始 JSON

对于 null 和空文本,CSV 单元格都可能看起来是空白。只有原始 JSON 能告诉你当时是哪一种。零个赞是真实的。False 是一个真实的认证值。Null 不是零,null 也不是 false。

4. 导入 CSV 时把 ID 存成文本

从数据集把工作副本下载为 CSV 或 Excel。对于 CSV,打开 Excel,使用“数据”,然后选择“自文本/CSV”。加载文件之前,检查每一列的类型。Microsoft 在导入或导出文本或 CSV 文件中说明了这条导入路径。

把 `postId`、`commentId` 和 `ownerId` 设为文本。真实的来源 ID 常常看起来像很长的数字。数字列可能丢掉长 ID 里的数位。`text` 保持为文本。只有当 `createdAt` 和 `collectedAt` 仍然与 JSON 一致时,才把它们存为日期和时间。UTC 是各地共用的世界时钟。它不使用你的本地时区。如果 Excel 改动了时钟,就把时间改为文本保存。不要信任 Excel 猜出的类型。

导入之后,拿一个 `commentId` 和一个 `createdAt` 与未经改动的 JSON 对比。也对比行数。下一节为这次检查提供一个虚构的文本测试。

5. 编码之前先计行数

把工作文件与原始 JSON 核对。数行数。数不为空白的不同评论 ID。不同是指同一个 ID 只计一次。找出复制的行。找出没有评论 ID 的行。用 JSON 区分 null 和空值。

虚构的导入测试

下一个文件是虚构的。虚构是指我们为了教学编造了它。它不是 Actor 的结果。它不属于下面的八行计数。它也不是一次真实 Excel 运行的结果。

测试 ID 是 `1234567890123456789`。这个 ID 有 19 位数字。把它存为文本。预期的 ID 正好是这 19 位数字。本文不编造一个从 Excel 得出的错误数字。它告诉你必须仍然看见的那些数位。

测试文本里有一个逗号、一次换行、引号,以及 café 这个词。字母 é 不在基本英语 A 到 Z 字母表里。文件必须保留 é。

下面这份 JSON 是虚构来源:

json
{
  "commentId": "1234567890123456789",
  "text": "Nice, work\nShe said \"hello\" at the café"
}
5. 编码之前先计行数

在 JSON 里,`\n` 表示一次换行。下面这份 CSV 是同一条虚构行。引号包住的文本里含有一次真实换行。内部引号写成两个。这是正常的 CSV 写法。

csv
commentId,text
"1234567890123456789","Nice, work
She said ""hello"" at the café"
5. 编码之前先计行数

正确导入之后,ID 仍然是:

text
1234567890123456789
5. 编码之前先计行数

文本仍然是:

text
Nice, work
She said "hello" at the café
5. 编码之前先计行数

这些是预期保留的值。它们不是你电脑上的一份报告。如果 ID 列是数字,或者 café 丢掉了 é,就停下来并修正导入。不要在损坏的文件上开始编码。

虚构的八行研究文件

下面八行也是虚构的。它们不是 Actor 的结果。它们不是那次已核对的三行运行。它们是来自一条虚构帖子的一份教学文件。不要把这些计数抄进真实论文。

每一行共用这些帖子值:

  • `postUrl`:`https://www.instagram.com/p/EXAMPLE0001/`
  • `postId`:`1000000000000000001`
  • `postShortCode`:`EXAMPLE0001`
  • `collectedAt`:`2026-10-13T12:00:00Z`

`postId` 有 19 位数字。在真实导入中它必须是文本。八条评论行仍然属于一条帖子。不要数成八条帖子。

在表中,null 表示不可用。空表示文本没有任何字符。简短的所有者标签 A、B、C 和 D 代替来源 ID。真实的所有者 ID 可以很长。也把它们存为文本。

5. 编码之前先计行数
行commentIdtextownerIdownerUsernamelikesCountrepliesCountownerVerifiedcreatedAt
R1C1很棒的帖子Aname_a2nullfalse2026-10-01T10:00:00Z
R2C1很棒的帖子Aname_a2nullfalse2026-10-01T10:00:00Z
R3C2很棒的帖子Aname_a1nullfalse2026-10-02T10:00:00Z
R4C3照片不错Bname_b00false2026-10-03T10:00:00Z
R5C4喜欢这个Cname_c4nullfalse2026-10-04T10:00:00Z
R6C5太棒了Dname_d3nullfalse2026-10-05T10:00:00Z
R7C6空nullnullnullnullnull2026-10-06T10:00:00Z
R8null很酷nullnullnullnullnull2026-10-07T10:00:00Z

R1 和 R2 的来源值相同。R2 是一条复制出来的导出行。复制行重复同一个评论 ID 和相同的来源值。R3 用了同样的文字“很棒的帖子”,但它的评论 ID 是 C2。C2 是另一条评论。它的时间和点赞数也不相同。这些差别帮助你把它认出来。即使其他字段相同,评论 ID 也足够用来区分。

在 R4 上,`likesCount` 为 0 表示零个赞。`repliesCount` 为 0 表示来源显示的回复数是零。你仍然没有回复正文。`ownerVerified` 为 false 表示来源把该账号显示为未认证。在 R7 上,null 并不表示零或 false。C6 的文本为空。本示例没有把 C6 的文本写成 null。CSV 工作副本可能让这段空文本、null 所有者、null 点赞数、null 回复数和 null 认证标记看起来全是空白。编码 C6 之前先使用原始 JSON。

按这个顺序计数:

原始行是每一行,包括复制行。原始行 = 8。

R2 是多出来的复制行。多出的复制行 = 1。

R8 没有评论 ID。没有评论 ID 的行 = 1。

已知的不同评论 = 8 - 1 - 1。那就是 6。这六个 ID 是 C1、C2、C3、C4、C5 和 C6。

C6 的文本为空。文本为空的已知评论 = 1。

文本基数 = 6 - 1。那就是 5。文本基数是有文本、可以编码的已知评论。这些评论是 C1、C2、C3、C4 和 C5。

你也可以从含有文字的行开始。R1、R2、R3、R4、R5、R6 和 R8 有文字。那是 7 行。去掉复制行 R2 和未定行 R8。7 - 1 - 1 = 5。两种算法得到的文本基数相同。

5. 编码之前先计行数
计数如何得到结果
原始行R1 到 R88
多出的复制行R2 复制了 R11
没有评论 ID 的行R81
已知的不同评论8 - 1 - 16
文本为空的已知评论C61
文本基数6 - 15
有所有者的已知评论C1 到 C55
已知的不同账号A、B、C 和 D4

R1、R2 和 R3 都写着“很棒的帖子”。C1 只计一次,因为 R1 和 R2 共用一个 ID。保留 C2,因为它的 ID 不同。如果你去掉重复的文字,就会丢失一条真实评论。如果你把每一条匹配的行都留下来,就会把 C1 计两次。

六条已知评论上的所有者值是 A、A、B、C、D 和 null。五条已知评论有所有者:C1 到 C5。账号 A 既写了 C1,也写了 C2。已知的不同账号 = 5 - 1。那就是 4。这四个账号是 A、B、C 和 D。五个所有者值是五条评论,不是五个账号,也不是五个人。

所有者不是 null 的原始行是 R1、R2、R3、R4、R5 和 R6。这个计数是 6。6 作为评论总数是错的,因为 R2 是复制行。去掉复制行之后,还剩五个所有者值。5 作为账号总数仍然是错的,因为 A 出现了两次。

这个文件没有人员字段。一个人可能使用两个账号。两个人可能共用一个账号。报告 4 个已知账号。不要报告 4 个人。不要报告 5 个人。C6 是一条所有者为 null 的已知评论。不要给 C6 写成所有者 0。在这个文件里,六条已知评论和四个已知账号都是对的。它们不是同一个计数。

R8 的文本是“很酷”,有一个时间,但没有评论 ID。没有别的行写着“很酷”。这仍然不能使 R8 成为一条已知评论。时间不能代替评论 ID。不要因为两者的所有者都是 null,就把 R8 和 C6 合并。共同的 null 不是一次匹配。没有证明 R8 是一条新评论。也没有证明它是一条复制行。在你核对原始 JSON 之前,把它保持为未定。不要按空白的评论 ID 合并。

只有当某个度量需要有文本的已知评论时,才把 5 用作基数。把 C6 保留在可获得性计数里。可获得性是指该值当时是否存在。对于针对全部已知评论的度量,基数是 6。把基数写在度量旁边。不要把 8、6 和 5 当成同一个基数来用。本示例不计算称赞所占比例或任何其他结果。

带有 `createdAt` 的已知评论 = 6 条中的 6 条。在本示例中,没有日期的已知评论 = 0。R8 有一个时间,但那个时间没有给它一个评论 ID。真实运行可能不同。如果你使用了日期筛选,`createdAt` 为 null 的评论本来就会被跳过。

6. 在原始文本旁边添加编码

把来源文字保留在 `raw_text` 里。不要在那里改正拼写。不要在那里去掉换行。如果你需要整理后的文字,把它们放进新列,例如 `coding_text`。把每一个选择放进新列:`coding_unit`、`code`、`coder`、`decision_note` 和 `coding_version`。

`coding_unit` 标出你编码的对象。在这个练习里,单位是评论。`code` 是你手工给出的标签。`coder` 标出作出选择的人。`decision_note` 说明原因。`coding_version` 标出这套规则。如果规则改变,写一个新版本。不要悄悄覆盖旧笔记。

只有这些列仍然填着,第二个人才可以重复这一选择。Actor 不会填写这些列。

同一份虚构文件在这里继续。这些标签是一位名叫 casey 的虚构编码员做的练习标记。它们不是 Actor 的字段。它们不是情感分数。它们不是关于真实人物的发现。

6. 在原始文本旁边添加编码
commentIdraw_textcoding_unitcodecoderdecision_notecoding_version
C1很棒的帖子commentin_text_basecasey与复制行的来源值相同。C1 只计一次。v1
C2很棒的帖子commentin_text_basecasey文字与 C1 相同。评论 ID 不同,所以两条都保留。v1
C3照片不错commentin_text_basecasey评论 ID 不同,账号是 B。v1
C4喜欢这个commentin_text_basecasey评论 ID 不同,账号是 C。v1
C5太棒了commentin_text_basecasey评论 ID 不同,账号是 D。v1

C1 和 C2 仍然是两个单位,因为它们的评论 ID 不同。账号 A 写了这两条。如果单位是账号,就会把它们归到一起。单位是评论时则不会。

C6 不进入这张练习表,因为它的文本为空。把 C6 保留在可获得性计数里。R8 不进入,因为它没有评论 ID。不要为了硬把它放进文本基数而给 R8 一个编码。

如果来源帖子后来消失,把带有日期的文件保留为 `collectedAt` 当时的观察记录。不要为了配合一个已经不见的页面而修改旧文字。留存规则是另一项书面选择,规定你把文件保留多久、谁可以查看。本文不设定那条规则。

7. 写下样本台账

台账是一份书面计数,记下你请求了什么、保存了什么,以及你排除了什么。用原始 JSON 和 OUTPUT 来编制。下面这份虚构台账只使用编造的行。本示例没有 OUTPUT 报告。凡是真实运行必须从 OUTPUT 抄写的地方,本示例都写成未知。

7. 写下样本台账
台账项目虚构文件中的值
请求的帖子1 条虚构帖子
保存的行8
多出的复制行1
已知的不同评论6
文本基数5
文本为空的已知评论1
未定的行1
已知的不同账号4
带有日期的已知评论6
没有日期的已知评论0
可用目标本示例中未知。请读 OUTPUT。
失败目标本示例中未知。请读 OUTPUT。
空目标本示例中未知。请读 OUTPUT。
达到上限的目标本示例中未知。请读 OUTPUT。

在真实运行中,从 OUTPUT 抄写 `requestedTargets`、`savedRows` 和 `cappedTargets`。为每条帖子抄写 `resultState`、`sampleHealth` 和 `stopReason`。然后自己去数不同的评论 ID。不要用猜测替换报告中的值。不要把本示例里的数字贴进那份报告。

7. 写下样本台账
项目你要做的事原因
R2不要把它计入评论总数它是 C1 的复制行,来源值相同
C6只把它排除在文本基数之外文本为空。仍把它计入可获得性计数
R8把它单独放在未定清单上没有评论 ID。不要按空白 ID 合并

在每一行旁边写下排除原因。默认顺序和公开可见性会改变哪些人的评论出现。在台账笔记里说明这一点。达到上限的目标碰到了你设置的上限。它本身不会点名每一条被留在外面的评论。

来源显示总数是帖子页面上显示的评论数。把它和保存的行分开。你将在方法说明里同时使用这两个数字。

8. 写一份与文件相符的方法说明

写下你实际保存了什么。说明这些行是公开展示的顶层评论。写明帖子链接、顺序、上限、日期窗口和采集时间。把来源显示总数和保存的行分开。

如果这两个数字不同,单凭差额不知道原因。这个差额不能证明采集有错误。这个差额也不能证明采集是完整的或没有差错的。上限、信息流停止、时间停止、来源失败、隐藏评论,或者从来不是数据行的回复,都可能改变计数。你的 OUTPUT 笔记才是记录你实际看到的停止情况的地方。

如果保存的行是零,不要写成该帖子没有评论。先阅读目标状态。

这些文字是模板。把每个括号换成你自己的运行结果。不要把虚构计数抄进去。

text
We saved publicly shown top-level comments.
The posts were the public URLs we listed before the run.
The order was default.
The cap per post was [your cap].
The collection time was [collectedAt].
The date window was [your dates], or we did not use a date filter.
We saved [saved rows] rows.
The source displayed total was [source total], or we did not record one.
A difference between those numbers is not proof of a bug.
That difference is also not proof that the file is complete.
We did not export reply text.
Null means a value was unavailable.
We kept zero and false as real values.
We counted comments, accounts, and posts separately.
This file describes the saved public comments only.
It does not describe all Instagram users.
8. 写一份与文件相符的方法说明

如果你没有记录来源显示总数,就把它留空。不要编造。第二个人应当能够把每一条已编码的评论追溯到一个评论 ID、一条帖子链接和 `collectedAt`。

来源和延伸阅读

作者 Chronometrica · 更新日期

返回顶部 ↑