

# 如何保存可互相比較的 Bing 關鍵字排名快照

保存每次 Bing 排名時，須一併記錄相同的查詢、國家、語言、設定、結果數量上限及觀察時間。排名是結果在所收集樣本中的位置編號。數字越小，表示結果越靠前。結果數量上限是每個查詢最多保留的結果數量。只有上述各項均相符的快照才可互相比較。快照是一次已保存的執行記錄。如果你的網頁沒有出現在設有數量上限的樣本中，應記錄為未在該樣本中出現。不要虛構排名。不要聲稱該網頁在整個 Bing 中都不存在。

## 你要保存的內容

Actor 是在託管環境中執行、用來收集資料的程式。本方法使用 [Google Search Scraper](https://apify.com/chronometrica/google-search-scraper) Actor，建置版本為 1.0.15。Task 是已保存的輸入預設。目前的 [Keyword Search Rank Snapshot](https://apify.com/chronometrica/google-search-scraper/examples/keyword-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](https://apify.com/chronometrica/google-search-scraper/examples/keyword-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](https://apify.com/chronometrica/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 列資料，兩列都是直接指向 docs.python.org 的網址。engine 為 bing。executedQuery 就是上述完全相同的字句。page 為 1。其中一列的 rank 為 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"
}
```

閱讀執行摘要

對照測試資料列的已知欄位值如下：

| 欄位 | 對照測試值 |
| --- | --- |
| engine | bing |
| executedQuery | Python asyncio documentation |
| page | 1 |
| rank | 1 和 2 |
| canonicalUrl | 2 個直接指向 docs.python.org 的網址 |
| observedAt | 每列都有 |

stopReason 的值為 result_caps_reached，表示該次執行已達到結果數量上限，並不表示 Bing 只有 2 項結果。

這次對照測試只檢查了範圍有限的 Bing 樣本。它檢查了網址、排名，以及已保存的查詢、搜尋結果頁和時間。它沒有測試 Google、Brave 或 DuckDuckGo，沒有測試每個搜尋運算子，也沒有測試每個國家。它沒有在之後再次檢查排名，沒有量度排名變動，沒有量度流量，也沒有擷取目的地網站的內容。

如果 enginesFailed 不是 0，不要聲稱目標不存在。查詢失敗時，不能將目標標示為不存在。

空樣本也不代表已涵蓋整個 Bing。達到上限、失敗和空樣本這些結果，都只描述該次執行。

## 以 8 個步驟比較快照

### 1. 選定目標及一份簡短的固定查詢清單。

查看排名變動前，先決定目標。指定網頁目標是事先聲明的 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. 稍後以相同輸入再次執行。

當你決定投入這筆預算時，再次執行該組固定輸入。將新快照保存為一筆[新的觀察記錄](/zh-Hant/articles/bing-%E6%90%9C%E5%B0%8B%E7%B5%90%E6%9E%9C-%E5%90%88%E4%BD%B5%E8%88%87%E5%8E%BB%E9%87%8D/)。不要覆寫舊記錄。

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 份網域快照，並非用來計算變動的 1 對快照。該網域有 2 個符合接受條件的網頁，自然搜尋排名分別為 3 和 8。如果目標是網域，觀察到的最佳排名就是 3。如果目標是指定指南網頁，該網頁的排名可以是 8，而同一網域上的另一個網頁可同時排名第 3。請說明你採用哪個定義。不要將 3 報作指定網頁的排名。

| 查詢 | 目標判定規則 | S1 狀態 | S2 狀態 | 排名變動 | 證據支持的結論 |
| --- | --- | --- | --- | --- | --- |
| Q1 | 指定網頁 https://garden.example/guide | observed_rank 7 | observed_rank 4 | 7 - 4 = +3 | 已知排名配對，均來自同樣只保留前十項結果的樣本 |
| Q2 | 指定網頁，上限 10 | observed_rank 2 | not_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，沒有量度變動。

## 下一步

保存 1 份 Bing 快照，並記錄完全相同的查詢、國家、語言、safeSearch 設定、贊助結果設定及結果數量上限。記錄 1 個有效的目標狀態：已觀察到排名、在上限範圍內未見目標、來源收集失敗，或無法確定目標。從 [Google Search Scraper](https://apify.com/chronometrica/google-search-scraper) Actor 及目前的 [Keyword Search Rank Snapshot](https://apify.com/chronometrica/google-search-scraper/examples/keyword-rank-snapshot) Task 開始。進行任何比較前，先將該 Task 改為只有 1 個查詢，並將 engines 設為 ["bing"]。

## 來源與延伸閱讀

- [Google Search Scraper](https://apify.com/chronometrica/google-search-scraper)
- [Keyword Search Rank Snapshot](https://apify.com/chronometrica/google-search-scraper/examples/keyword-rank-snapshot)
- [https://www.reddit.com/r/SEO/comments/1dybuk8/any_tools_to_just_monitor_specific_keyword_ranking/](https://www.reddit.com/r/SEO/comments/1dybuk8/any_tools_to_just_monitor_specific_keyword_ranking/)
- [https://www.reddit.com/r/SEO/comments/1d5kve4/how_to_check_if_you_ranked_on_a_keyword/](https://www.reddit.com/r/SEO/comments/1d5kve4/how_to_check_if_you_ranked_on_a_keyword/)