2份搜索结果列表将不同已保存观测记录中的同一页面连接起来。
对比排名前,先固定查询设置。

你保存的是什么

Actor 是用于采集数据的托管程序。本方法使用 Google Search Scraper Actor,构建版本为1.0.15。Task 是已保存的输入预设。当前的 Keyword Search Rank Snapshot Task 仅提供起始输入,本身不会分析排名。

Actor 保存来源数据行。你需要按照下列步骤对比这些数据行。

构建版本1.0.15的 engines 列表可接受 Google、Bing、Brave 和 DuckDuckGo。本方法只接受 Bing。不要将 Google、Brave 和 DuckDuckGo 纳入这份台账。一条暂缓采用的 Google 处理路径返回了重定向地址,无法直接看出最终网站。这些地址不属于本方法认可的目标网址。

台账是记录快照的表格。这份台账不表示 Google Search Console 的平均排名,也不表示每个人看到的排名。

设置 Bing 输入

当前的 Keyword Search Rank Snapshot Task 保存了以下输入:

json
{
  "queries": ["best CRM", "small business accounting software", "AI marketing tools"],
  "engines": ["google", "bing", "brave", "duckduckgo"],
  "maxResultsPerExecutedQuery": 20,
  "country": "US",
  "language": "en",
  "safeSearch": true,
  "includeSponsoredResults": false
}
设置 Bing 输入

替换整个 queries 列表。替换整个 engines 列表。首次检查时,使用1个你计划跟踪的查询。将 engines 设为 ["bing"]。将 maxResultsPerExecutedQuery 设为2。将 country 和 language 设为以后将重复使用的组合。保持 safeSearch 为 true。保持 includeSponsoredResults 为 false。

该输入没有扩展设置,也没有公开的页数限制字段。结果数量上限由 maxResultsPerExecutedQuery 指定。不要添加页数上限字段。

在请求中指定国家并不能消除个性化。个性化是指 Bing 仍可能向不同的人显示不同的结果。指定国家不能保证结果与每位当地用户看到的结果一致。

首次检查时,使用以下结构。将你的实际查询词填入 queries:

json
{
  "queries": ["one intended phrase"],
  "engines": ["bing"],
  "maxResultsPerExecutedQuery": 2,
  "country": "US",
  "language": "en",
  "safeSearch": true,
  "includeSponsoredResults": false
}
设置 Bing 输入

只有确定以后会持续使用新的 country 和 language 组合时,才更改这些设置。此后每份快照都记录相同的值。

首次对比前,固定以下选项:

  • 完全一致的查询文本
  • country
  • language
  • safeSearch
  • includeSponsoredResults
  • maxResultsPerExecutedQuery

之后更改数量上限,可能会使结果呈现的顺序发生变化。之后更改结果读取方式,也可能产生同样的影响。对比时,保持采集范围相近。

读取每条结果数据

每行数据表示在1个搜索引擎、1个查询、1个结果页和1个位置上观测到的1条结果。Actor 可以在一次运行中保留多个查询,不会将这些查询合并为每个网站仅1行的数据。本方法要求每次运行只包含1个 Bing 查询。

以下是 Google Search Scraper Actor 数据行中的字段,名称与原字段完全一致:

  • runId
  • country
  • language
  • safeSearch
  • engine
  • executedQuery
  • page
  • rankOnPage
  • rank
  • title
  • canonicalUrl
  • resultDomain
  • snippet
  • isSponsored
  • advertiserDomain
  • observedAt
  • schemaVersion

rank 表示结果在该次运行所采集样本中的位置。rankOnPage 表示结果在该结果页上的位置。page 表示结果页的页码。

canonicalUrl 是 Actor 清理链接后保存的地址字符串。它是一个候选地址,并非经过核查的 HTML rel=canonical 链接,也不是原始 href 的完全复制。保持返回的字符串不变。这个字符串就是你的来源证据。

snippet 是搜索结果中的文本,不是目标网站的文章正文,也不能证实该网站上的某项说法。

isSponsored 表示该行是否为付费结果。自然搜索结果是非付费结果。将付费和非付费数据行分开。当 includeSponsoredResults 设为 false 时,不要将赞助结果行的排名视为自然搜索排名。

advertiserDomain 可能出现在赞助结果行中。它不表示另一个自然搜索排名。

数据行中的 country、language 和 safeSearch 是请求中指定的条件,不保证每个个性化结果都符合这些条件。

Actor 不会打开目标网站,不会移除所有多余的页面文本,不会核查引用,不会给销售表现评分,也不会安排下次运行。如果你需要检查目标网站,就需要自行检查。

读取运行摘要

OUTPUT 是运行摘要,与各条结果数据分开保存。两者都要读取。OUTPUT 使用以下字段:

  • queriesRequested
  • searchesCompiled
  • executionsPlanned
  • enginesSuccessful
  • enginesFailed
  • pagesAttempted
  • pagesParsed
  • resultsSaved
  • engineStatusCounts
  • engineResultCounts
  • queryResultCounts
  • stopReason

该 Actor 当前的一次 Bing 对照检查使用了查询词 Python asyncio documentation。Actor 尝试处理1个结果页,并成功解析该页。它保存了2行数据。2行都是直达 docs.python.org 的网址。engine 为 bing。executedQuery 与上述查询词完全一致。page 为1。其中1行的 rank 为1,另1行的 rank 为2。每行都有 observedAt。

该对照检查的 OUTPUT 如下:

json
{
  "queriesRequested": 1,
  "searchesCompiled": 1,
  "executionsPlanned": 1,
  "enginesSuccessful": 1,
  "enginesFailed": 0,
  "pagesAttempted": 1,
  "pagesParsed": 1,
  "resultsSaved": 2,
  "engineStatusCounts": {"bing": {"ok": 1}},
  "engineResultCounts": {"bing": 2},
  "queryResultCounts": {"Python asyncio documentation": 2},
  "stopReason": "result_caps_reached"
}
读取运行摘要

已知的对照检查数据行字段值如下:

读取运行摘要
字段对照检查值
enginebing
executedQueryPython asyncio documentation
page1
rank1和2
canonicalUrl2个直达 docs.python.org 的网址
observedAt每行都有

stopReason 的值为 result_caps_reached,表示运行已达到结果数量上限,并不表示 Bing 只有2条结果。

这次对照检查只核查了一个范围有限的 Bing 样本。它核查了网址、排名,以及保存的查询、结果页和时间。它没有测试 Google、Brave 或 DuckDuckGo,没有测试所有搜索运算符,也没有测试所有国家。它没有在之后再次观测排名,没有测量排名变化,没有测量流量,也没有提取目标网站内容。

如果 enginesFailed 不为0,不要声称目标不存在。查询失败时,不能将目标记为不存在。

空样本也不代表覆盖了整个 Bing。达到数量上限、失败和空结果,都只描述该次运行的情况。

按8个步骤对比快照

1. 选择目标和一份简短、固定的查询列表。

查看排名变化前,先确定目标。精确页面目标是事先声明的单个地址及其路径。域名目标是同一主机上符合认定条件且排名最靠前的页面。说明判断采用了哪一种目标定义。简短、固定的列表,是指每次重复使用相同的查询词。首次检查仍只使用1个查询词,且只使用 Bing。添加其他查询词时,必须将其作为独立的固定行,并使用相同的设置。

范围有限的 Bing 台账不报告 Google Search Console 的平均排名,也不报告每个人看到的排名。

2. 固定使用 Bing,并锁定样本设置。

将 Task 的引擎列表替换为 engines ["bing"]。首次检查时,将示例查询替换为1个你计划跟踪的查询。在这次试运行中,将 maxResultsPerExecutedQuery 设为2。固定 country、language、safeSearch、includeSponsoredResults 和结果数量上限。

相同查询词在不同国家产生的快照不同。开启和关闭安全搜索产生的快照不同。数量上限为2和为10的快照不同。在请求中指定国家,仍不能保证结果与每位当地用户看到的结果一致。

3. 检查成功返回的数据行和 OUTPUT。

保留每条成功返回的数据行中的 executedQuery、rank、rankOnPage、page 和 observedAt。在这些数据旁保留 OUTPUT 中的各项计数和 stopReason。当前的小规模对照检查在第1个结果页上得到了2个带排名的直达网址。这次对照检查没有测量你的页面的排名变化。

如果查询失败,不要将目标记为不存在,而应保存为 source_failed。

4. 按预先确定的规则匹配目标。

对于精确页面,按你事先声明的地址和路径规则进行比对。保留返回的 canonicalUrl。不要更改返回的字符串。

对于域名,匹配指定的主机。在该主机符合认定条件的自然搜索结果行中,保留最小的 rank。这个最小值就是该域名在样本中观测到的最佳排名。

不要因为公司名称相似就合并结果。不要合并不同子域名的结果。不要合并跟踪重定向结果,除非你已检查该重定向并认可其目标地址。如果无法确认身份,状态应为 unresolved_target。

5. 保存1个有效状态。绝不保存虚假排名。

当目标与某行匹配时,使用 observed_rank。有用的样本应来自一次已完成且成功的运行,并记录了数量上限。如果这样的样本中没有目标,使用 not_seen_within_cap。如果采集失败,使用 source_failed。如果无法判断某行是否为目标,使用 unresolved_target。

不要使用0,也不要使用 cap + 1。这些数字看起来像排名,但并非观测到的排名。

试运行的数量上限为2时,未找到目标应记为上限2以内的 not_seen_within_cap。该页面可能出现在更后面的位置。真实排名仍然未知。以后固定使用任何更大的上限时,也适用同一规则。

6. 之后使用相同输入再次运行。

当你决定投入这笔预算时,用固定的输入再次运行。将新快照保存为一条新的观测记录。不要覆盖旧记录。

Task 本身不会监测排名。定时运行需要你另行设置。对比时,使用相同的查询和目标规则。使用相同的 country、language 和 safeSearch 值。使用相同的赞助结果设置,并保持采集范围相近。

如果数量上限发生变化,就不能称这对快照具有可比性。如果结果读取方式发生变化,也不能称这对快照具有可比性。

7. 只有2个排名都已知时,才计算变化。

排名变化用简单的减法计算。排名变化 = 旧排名 - 新排名。结果为正数,表示新排名的数字更小。该结果在新样本中的位置比在旧样本中更靠前。

不要将 not_seen_within_cap 纳入减法计算。source_failed 和 unresolved_target 也不能纳入。不要将未知值与真实排名一起计算平均值。不要将0或 cap + 1这类替代数字纳入平均值。

样本中顺序的变化,不能证明流量发生了变化,不能证明销售发生了变化,也不能证明变化是由内容修改引起的。

8. 交付台账,仅对已知且可比的数据作比较。

为每个查询与目标规则的组合建立1行台账。记录来源运行、查询条件、数量上限、状态和对比说明。将 Google 和其他引擎的数据另行保存,不要在这里对它们作出结论。

最后给出1组条件匹配的快照对比,或注明尚无法确定对比结果。不要用猜测的排名填补空缺。

虚构的排名台账

下表为原创虚构示例,用于说明各类状态。它不是 Actor 的运行结果,也不是上文的 Bing 对照检查。虚构的目标页面为 https://garden.example/guide. 虚构的域名为 garden.example。S1 是较早的快照。S2 是较新的快照。Q1 的2份快照使用相同的 Bing 设置,数量上限都为前10条结果。试运行的数量上限为2,采集范围不同。不要混用这些上限。示例未提供日期,因此不显示日期。

Q1 对比的是指定的指南页面。S1 观测到排名为7,S2 观测到排名为4。2个排名都来自数量上限相同的前10条结果样本。排名变化 = 7 - 4 = +3。按此定义,该页面在样本中的位置向前移动了3位。

Q2 使用同一个精确页面,数量上限也同为10。S1 观测到排名为2。S2 的状态为上限10以内的 not_seen_within_cap。新排名未知,排名变化也未知。不要保存为11。该页面可能排在第10位之后,但你不知道它在更后面哪个位置。

Q3 使用同一个精确页面。示例未提供 S1 的排名和时间,因此 S1 仍为未知。S2 为 source_failed。无法进行对比。这不是排名下降。失败表示未能采集到新样本。

Q4 是1份域名快照,不是一组用于计算变化的快照。该域名上2个符合认定条件的页面,其自然搜索排名分别为3和8。如果目标是域名,观测到的最佳排名就是3。如果目标是指定的指南页面,该页面的排名可能为8。同时,该域名上的另一个页面可能排名为3。说明你使用了哪一种定义。不要将3报告为该精确页面的排名。

虚构的排名台账
查询目标规则S1 状态S2 状态排名变化可稳妥得出的结论
Q1精确页面 https://garden.example/guideobserved_rank 7observed_rank 47 - 4 = +3一组已知排名,均来自数量上限相同的前十条结果样本
Q2精确页面,上限10observed_rank 2not_seen_within_cap 10未知不能记为排名11,也不能将排名变化记为2 - 11
Q3精确页面未知source_failed未知无法对比,不表示排名下降
Q4域名 garden.example,或指定的指南页面1份快照:符合认定条件的排名为3和8同一份快照,并非另一个时间点无域名的最小排名为3。指定指南页面的排名可能为8

有人可能会编造 Q2 的排名为11,再计算2 - 11 = -9。这个-9不是观测结果。将 Q1 的+3与这个虚假的-9一起计算平均值,会得到错误的汇总结论。先展示2个已知排名的对比,再展示仅在限定样本内未见目标的情况,以及来源采集失败的情况。计算任何平均值时,都应排除未知状态。

这些 S1 和 S2 值是教学台账中的状态,不是对照检查输出的原生排名字段。该对照检查只保存了排名1和2,并未测量变化。

来源和延伸阅读

作者 Chronometrica · 更新日期

返回顶部 ↑