

# Chronometrica 与 ScraperLink：为什么同一页 Google 搜索结果看起来重复了

如果你只需要原始页面结果，先在当前 ScraperLink 请求中设置 `include_merged:false`。ScraperLink 文档说明，默认输出包含一个内嵌结果列表的页面条目，以及一个额外的合并条目。此设置会关闭额外的合并条目。[ScraperLink Actor](https://apify.com/scraperlink/google-search-results-serp-scraper)

如果后续电子表格或 API 要求每个保存的条目对应一条搜索结果观测记录，再选择 Chronometrica。API 是供程序交换数据的接口。观测记录会保存一条结果及其搜索上下文，包括查询词和排名。Chronometrica 文档说明了这种行格式，以及针对每个搜索引擎和查询的结果行数上限。这种格式省去了将嵌套结果转成行的单独步骤。[Chronometrica Actor](https://apify.com/chronometrica/google-search-scraper)

如果你需要页面对象、可选的合并对象，或文档中说明的 `tbs`、`lr` 和 `cr` 控制参数，请继续使用 ScraperLink。这些需求会改变推荐结论。[ScraperLink Actor](https://apify.com/scraperlink/google-search-results-serp-scraper)

本次比较中的 Chronometrica Actor 由 Chronometrica 自行发布。Actor 是在托管平台上运行的数据采集程序。Task 是为 Actor 保存的一组输入预设。我们选择比较这两个产品，是为了回答一个问题：你的下一步处理需要页面对象，还是每条结果各占一行？

## 先明确你要统计的单位

一个数据集条目就是一个保存的对象。它并不总是代表一条搜索结果。一个页面对象可以在列表中包含多条结果。存放在另一个对象内部的列表称为嵌套数组。

统计结果前，先确定每个保存的条目代表什么。两个对象可能以不同形式呈现同一组观测记录。如果导入流程展开了这两种形式，所得总数就可能超过你原本要使用的观测记录数。

ScraperLink 的公开问题记录中，有读者提出过结果重复的疑问。这是一条已关闭的历史问题。它能说明读者存在这一疑问，但不能证明目前存在程序缺陷或服务中断。[历史结果重复问题](https://apify.com/scraperlink/google-search-results-serp-scraper/issues/duplicate-results-wh-FgWDpiOnt4BS2MjWa)

本文使用的公开产品输入输出规范已于 2026 年 10 月 20 日核查。我们没有进行条件匹配的采集运行，也没有核查实时结果。本次比较解释的是文档中说明的输入和输出格式。

以下 3 种计数回答不同的问题：

- 数据集条目数：保存了多少个对象？
- 结果观测记录数：所选搜索包含多少条结果记录？
- 不重复的目标页面数：这些记录中出现了多少个不同的目标页面？

查看总数前，先选择要统计的单位。即使保存对象的数量统计正确，也可能无法正确回答搜索结果有多少条。

## 直接修正当前请求

在所给示例中，使用以下 ScraperLink 输入：

```json
{
  "keyword": "Nike",
  "limit": "10",
  "page": 1,
  "include_merged": false
}
```

直接修正当前请求

当前公开的输入规范支持这些设置。请将 `limit` 保持为此处所示的字符串。此示例请求 1 页有数量限制的结果，并关闭合并输出。[ScraperLink 默认构建版本与输入模式](https://api.apify.com/v2/acts/scraperlink~google-search-results-serp-scraper/builds/default)

将 `Nike` 替换为你要使用的查询词。在把输出发送给其他程序前，先检查输出。

找到所选页面条目中的嵌套结果列表。统计其中的记录数。然后检查导入流程读取了哪个对象，展开了哪个列表。导入流程应只使用所需的结果形式 1 次。

不要把列表长度乘以保存的对象数。先确认这些对象包含的是不同的观测记录，还是同一组观测记录的不同呈现形式。

首次请求应保持小规模。它的目的是检查输出格式和计数规则。如果页面条目已经能满足下一步处理，当前需求就已得到解决。只有在明确了当前流程无法满足的另一项需求后，才考虑更换工具。

## 比较下一步处理需要的输出

验收规则是使用输出前必须满足的条件。请用下表制定这条规则。输入这一行列出了这些示例使用的设置，并不表示每个字段都是必填项。

| 决策要点 | 当前按页请求 | Chronometrica 结果行 |
| --- | --- | --- |
| 本示例所需的输入 | `keyword`, `limit`, `page`, `include_merged:false` | `queries`, `engines`, `maxResultsPerExecutedQuery`, `country`, `language` |
| 输出单位 | 包含嵌套结果的页面条目 | 数据集中每行对应 1 条搜索结果观测记录 |
| 验收规则 | 对所选结果列表中的记录只计数 1 次 | 每个通过验收的行都代表 1 条带有搜索上下文的观测记录 |
| 缺失值规则 | 保留未知值状态 | 保留未知值状态 |
| 选择条件 | 下一步处理接受页面对象，或会展开其中的列表 | 下一步处理要求直接提供结果行，无需展开嵌套列表 |

产品列依据当前文档中说明的规范编写。[ScraperLink Actor](https://apify.com/scraperlink/google-search-results-serp-scraper)、[Chronometrica Actor](https://apify.com/chronometrica/google-search-scraper)、[Chronometrica 输入模式](https://api.apify.com/v2/acts/chronometrica~google-search-scraper/builds/default)

展开是指将嵌套列表中的每条记录转换成单独的一行。展开时，要保留每条记录所属的搜索上下文。

如果现有的展开步骤运行正常，可以继续保留。具体选择取决于接收系统。如果它接受页面对象，更换输出格式可能没有实际价值。如果它要求单独的观测记录，则需要决定是保留展开步骤，还是直接接收这种行格式。

## 虚构示例：2 个对象不能证明有 20 条结果

这是一个虚构示例。它不是产品测试、实测结果或客户案例。

一位分析师请求了 1 页结果。在这个虚构示例中，原始页面包含 10 条嵌套的结果观测记录。一个可选的合并对象重复包含了这 10 条观测记录。

分析师看到 2 个保存的对象。其导入流程展开了这 2 个对象：

```text
10 observations from the raw page
+ 10 repeated observations from the merged object
= 20 imported sightings
```

虚构示例：2 个对象不能证明有 20 条结果

计算本身正确：10 + 10 = 20。但对结果的解读有误。这 1 页实际要统计的是 10 条观测记录。由于导入流程使用了两种呈现形式，电子表格中每条观测记录都出现了 2 次。

分析师关闭了合并输出。随后只读取原始页面的结果列表 1 次，并检查其长度。在这个虚构示例中，这样做避免了重复展开。

这个示例不能说明 Actor 抓取了同一页面 2 次，或收费 2 次。仅凭保存对象的数量，无法证明其中任何一种情况发生过。

之后，如果另一个 API 要求每个提交的条目代表 1 条观测记录，分析师就需要作出另一个选择。这位分析师可以保留展开步骤，也可以选择文档所述输出已符合这一要求的 Actor。

Chronometrica 符合后续的行格式要求。这个虚构总数不能证明其采集性能更好。

## 什么情况下 Chronometrica 更适合

Chronometrica 文档说明，数据集中每行对应 1 条搜索结果观测记录，包含搜索引擎、查询词、排名和上下文。文档还说明了 `maxResultsPerExecutedQuery`，该参数为每个实际执行的搜索引擎与查询组合设置结果行数上限。[Chronometrica Actor](https://apify.com/chronometrica/google-search-scraper)

可从以下输入示例开始：

```json
{
  "queries": [
    "Nike"
  ],
  "engines": [
    "google"
  ],
  "maxResultsPerExecutedQuery": 10,
  "country": "US",
  "language": "en"
}
```

什么情况下 Chronometrica 更适合

我们已对照当前公开的输入模式，核查键名、必填字段、允许值、列表长度范围和数值范围。此示例未实际运行。[Chronometrica 默认构建版本与输入模式](https://api.apify.com/v2/acts/chronometrica~google-search-scraper/builds/default)

这个上限只是最大值。它不能证明请求一定会恰好返回 10 条观测记录。报告数量前，请检查实际输出。

这种格式适合每行保存 1 条观测记录的电子表格。它也适合要求每个提交条目包含 1 条观测记录的 API。保存的单位与下一步处理所需的单位一致。

这种一致性省去了先展开嵌套结果列表的步骤。你仍需选择系统使用的字段、保留未知值状态，并检查输出。你也可能需要另外生成一份不重复的目标页面列表。

如果你需要的是这项已核查的格式匹配，可以选择 Chronometrica。现有证据不能证明它在速度、可靠性、准确性或成本方面更有优势。更换工具前，请从当前文档中确认其他必需功能。

## 更换工具前，完成 5 项检查

1. 查看当前的合并输出设置。确定流程需要哪种输出形式。将眼前的计数问题与后续选择行格式的问题分开处理。
2. **使用 `include_merged:false` 请求 1 页有数量限制的结果。**记录完整的实际输入。这样，你就能将输出与所请求的查询词和页码对应起来。
3. 统计嵌套结果的记录数。检查所选原始页面的结果列表。确认导入流程只读取该列表 1 次。将列表记录数与展开后生成的行数进行比较。
4. 定义下一步处理所需的单位。用一句话写明，例如：“每个导入行必须代表某个确切查询词下的 1 条结果。”将这句话作为验收规则。
5. 生成不重复的目标页面列表前，先保留搜索上下文。保留搜索引擎、确切的查询词、排名和可用的时间信息。如果时间由你自己的流程记录，请明确标注为你的记录时间。

这些检查帮助你作出 2 个决定。先判断能否正确统计当前输出。再判断其保存单位是否适合下一个系统。

对于手动处理的电子表格，展开步骤可能很容易检查。对于反复执行的导入流程，直接提供结果行可能更符合接收系统的要求。不要先假定它能节省时间，应先检查现有流程需要完成哪些工作。

如果以后要比较成本，请单独定义计费单位。保存的对象、结果观测记录和计费搜索是不同的概念。合并输出的总数不能证明计费搜索次数，也不能证明价格优势。

## 使用总数前，先检查导入流程

验收规则要足够具体，便于检查。总数不一致时，“输出看起来没问题”几乎无法提供帮助。一条实用的规则应明确源列表、计数单位，以及每个导入行必须保留的上下文。

先查看所选输出在展开前的内容。统计其中需要的观测记录数。再检查由该输出生成的行。如果两者总数不同，先检查导入流程读取了哪些对象和列表，再决定是否删除行。

删除重复 URL 的规则可能掩盖计数错误的原因。它还可能删除不同查询下的有效观测记录。应先纠正输出形式的选择。只有在需要单独统计目标页面时，才生成不重复的目标页面列表。

用清楚的文字记录检查结果。说明你统计的是页面对象、观测记录还是目标页面。这样，即使没有查看原始输出的人，也能正确使用这个总数。

## 区分观测记录与不重复的目标页面

同一目标页面可能出现在不同查询下。即使指向同一个页面，这些出现记录仍可能是不同的观测记录。

不重复的目标页面列表回答出现过哪些页面。观测记录回答某个页面在各个查询下出现的位置和排名。如果你需要这两种答案，就保留两种输出。

根据观测记录生成目标页面列表。同时保留这些观测记录，以便追溯每个目标页面的搜索上下文。不要仅因某条观测记录的 URL 也出现在另一个查询下，就删除这条记录。

当 2 个人报告不同总数时，这一区分也有帮助。其中一人可能统计的是观测记录，另一人统计的是目标页面。认定两者结果冲突前，先说明各自的计数单位。

如果后续需要合并不同运行的导出数据，请参阅[如何合并 Bing 搜索导出数据，同时保留查询词和排名证据](/zh-Hans/articles/%E6%90%9C%E7%B4%A2%E7%BB%93%E6%9E%9C%E5%90%88%E5%B9%B6-%E4%BF%9D%E7%95%99%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%90%8D%E8%AF%81%E6%8D%AE/)。该指南讨论跨运行合并。本次比较处理的是更早的步骤，即选择输出形式和保存单位。

## 导入时保留未知值状态

值缺失不等于值为 0。缺失的排名不应变成排名 0。未知的数量不应变成已确认的数量 0。

对于未知值，请留空，或使用接收系统支持的缺失值表示形式。记录这一选择，避免后续计算把缺失数据当成实测结果。

时间也应遵守同样的规则。不要编造来源时间戳。如果你只知道自己的流程何时收到数据，就保存该时间，并明确标注。

无论使用哪种输出格式，都要检查这些规则。单独的结果行可能更容易被接收系统接受，但仍需正确解读。行数正确，不能证明所有字段都存在，也不能证明每个值的含义都与你的报告假设一致。

## 先完成当前修正，再选择 Actor

如果需要原始页面结果，先在当前请求中设置 `include_merged:false`。只有当 Chronometrica 的结果行格式符合后续电子表格或 API 的要求时，才选择它。如果当前工具的页面对象或文档所述控制参数能满足需求，就继续使用当前工具。

如果你需要结果行，请打开 Chronometrica 的 [Keyword Search Rank Snapshot Task](https://apify.com/chronometrica/google-search-scraper/examples/keyword-rank-snapshot)。在 2026 年 10 月 20 日的核查中，该公开页面返回 HTTP 200，标题为 Keyword Search Rank Snapshot · Apify。我们未读取其保存的输入。请将其作为起始预设，并应用上文所示设置。

将示例查询词替换为你要使用的查询词。检查搜索引擎、国家、语言和结果数量上限。运行一个小规模请求，并按验收规则检查输出。如果每个保存行对应 1 条观测记录的格式符合下一步处理要求，请使用 [Chronometrica Google Search Scraper Actor](https://apify.com/chronometrica/google-search-scraper)。

## 来源和延伸阅读

- [Chronometrica Google Search Scraper：文档所述的输出和控制参数；已于 2026 年 10 月 20 日核查；公开文档支持文中所述的行格式和上限，未进行条件匹配的运行或实时结果核查](https://apify.com/chronometrica/google-search-scraper)
- [Chronometrica Google Search Scraper 默认构建版本：公开输入规范；已于 2026 年 10 月 20 日核查；已对照输入模式核查示例键名、必填字段、允许值和范围，未运行](https://api.apify.com/v2/acts/chronometrica~google-search-scraper/builds/default)
- [ScraperLink Google Search Results SERP Scraper：文档所述的页面输出和合并输出；已于 2026 年 10 月 20 日核查；当前文档支持文中所述的格式和控制参数，未进行条件匹配的运行或实时结果核查](https://apify.com/scraperlink/google-search-results-serp-scraper)
- [ScraperLink Google Search Results SERP Scraper 默认构建版本：公开输入规范；已于 2026 年 10 月 20 日核查；支持所给的直接修正输入，未运行](https://api.apify.com/v2/acts/scraperlink~google-search-results-serp-scraper/builds/default)
- [ScraperLink 历史结果重复问题：读者遇到的问题；已于 2026 年 10 月 20 日核查；这是一条已关闭的历史问题，能说明读者需求，不能证明当前存在程序缺陷或服务中断](https://apify.com/scraperlink/google-search-results-serp-scraper/issues/duplicate-results-wh-FgWDpiOnt4BS2MjWa)
- [Keyword Search Rank Snapshot · Apify：可作为起点的公开 Task；已于 2026 年 10 月 20 日核查；页面返回 HTTP 200，并显示此标题，但未读取已保存的输入，也未验证任何输出](https://apify.com/chronometrica/google-search-scraper/examples/keyword-rank-snapshot)
- [如何合并 Bing 搜索导出数据，同时保留查询词和排名证据：关于合并不同运行导出数据的相关指南；已在 2026 年 10 月 20 日的简报中核查范围；其主题不同于本文对页面对象与结果行的比较](https://chronometrica.com/zh-Hans/articles/%E6%90%9C%E7%B4%A2%E7%BB%93%E6%9E%9C%E5%90%88%E5%B9%B6-%E4%BF%9D%E7%95%99%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%90%8D%E8%AF%81%E6%8D%AE/)