

# 如何合併 Bing 搜尋匯出資料，同時保留查詢及排名證據

將搜尋結果觀測記錄和目標網址分別合併至獨立的資料表，以保留查詢、排名及時間證據。Actor 是託管的資料收集程式。Task 是已儲存的輸入預設設定。canonicalUrl 是回傳的標準化候選網址，並非經核實的 HTML 標準網址或原始 href。snippet 是搜尋來源提供的文字，並非擷取回來的文章內容。

設定 Apify Google Search Scraper 組建版本 1.0.15 時，請將已儲存的整份範例查詢清單和搜尋引擎清單，分別替換為你要使用的查詢詞組及 `["bing"]`，並使用以下輸入 JSON：`{"queries": ["Python asyncio documentation"], "engines": ["bing"], "maxResultsPerExecutedQuery": 2, "country": "US", "language": "en", "safeSearch": true, "includeSponsoredResults": false}`。請注意，公開組建版本 1.0.15 支援多個搜尋引擎，但本文只有 Bing 通過驗收；Google、Brave 和 DuckDuckGo 的處理流程暫緩驗收或不在範圍內。對照測試的 OUTPUT 執行摘要列出以下計數：`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"。這些執行摘要計數反映擷取程式的執行總數，並非各個目標的資料列數。這次測試只確認了在限定範圍內對 Bing 網址、排名和來源追溯資料的支援，並未確認未通過驗收的其他搜尋引擎、其他市場，或目標網頁擷取功能。

## 1. 設定資料收集規則

1. 設定資料收集規則時，請將已儲存的整份查詢清單和搜尋引擎清單，分別替換為 1 個要使用的查詢詞組及 `["bing"]`，並設定 `maxResultsPerExecutedQuery: 2`、國家為美國、語言為英語、`safeSearch: true` 及 `includeSponsoredResults: false`。本文沒有指定任何公開的頁數上限輸入設定。
2. 儲存原始 Bing 結果資料列和 OUTPUT 中繼資料。原生資料列欄位包括 `runId`、`country`、`language`、`safeSearch`、`engine`、`executedQuery`、`page`、`rankOnPage`、`rank`、`title`、`canonicalUrl`、`resultDomain`、`snippet`、`isSponsored`、`advertiserDomain`、`observedAt` 及 `schemaVersion`。保留完整資料，以識別每次執行及其設定。
3. 使用 `runId` + `engine` + `executedQuery` + `page` + `rankOnPage` 建立觀測鍵。保留 rank 和 observedAt 作為證據。從工作表移除完全相同的匯出重複資料列，並記錄移除的重複項目。如果重複出現的鍵對應互相衝突的網址值，請保留 2 個候選值，待查核來源；不要自行選擇，也不要依多數決定。
4. 根據回傳的 `canonicalUrl` 建立目標鍵；這個值是標準化候選網址，並非 HTML 標準網址的證明或原始 href。先使用回傳的完整網址字串。如果要統一主機名稱的大小寫、處理片段識別碼或追蹤參數，請記錄為何這些變更不會改變目標。不同的路徑或查詢參數仍須分開保留。
5. 透過目標鍵欄位，將觀測記錄連結至目標表。同一網址若由 2 個查詢找到，或在 2 個時間點找到，便會有多筆觀測記錄，但只有 1 個經審核的目標。網址與查詢之間的歸屬關係只能根據實際觀測記錄建立。
6. 安全地匯出工作表。確保查詢中的引號、逗號、換行和 Unicode 字元完整保留。請以原始 JSON 或 JSONL 作為主要參考，因為 CSV 匯出或匯入工具可能無法保留 null 與空值之間的差別。合併大型匯出資料前，先用小型測試資料確認匯出再匯入後，所有值均完全一致。
7. 分別報告原始資料列、匯出重複資料列、不重複的有效觀測記錄、衝突，以及不重複目標鍵的數量。不重複網址數或查詢歸屬關係不能用來估算搜尋總量或所有網站的數量。在資料收集記錄中保留失敗、沒有結果或已達上限的搜尋。
8. 將目標網址和觀測記錄參照交給[獨立的目標檢查流程](/zh-Hant/articles/%E5%BE%9Ebing%E6%90%9C%E5%B0%8B%E7%B5%90%E6%9E%9C%E5%BB%BA%E7%AB%8B%E7%88%AC%E5%8F%96%E4%BD%87%E5%88%97/)。合併資源並不能證明網頁可供存取、內容相關或來源可靠。請明確說明範圍只涵蓋 Bing。

## 虛構的合併記錄表與資料檢查

*註：以下表格和記錄均為原創虛構內容，只供教學之用。*

假設有一項測試：執行 R1 使用查詢 "AI agents"，得到排名 1 的 U1 和排名 2 的 U2。執行 R1 使用查詢 "small business automation"，得到排名 1 的 U2 和排名 2 的 U3。執行 R2 使用查詢 "AI agents"，得到排名 1 的 U1 和排名 2 的 U4。所有結果均來自 Bing，並按聲明使用相同設定，但各有自己的觀測時間。6 個觀測鍵對應 4 個目標鍵：U1、U2、U3 和 U4。U1 有 2 個時間點的觀測記錄；U2 有來自 2 個查詢的觀測記錄。這 2 種重複出現的情況都不屬於匯出重複資料列。

第 7 筆原始資料列完全重複 R1 / 查詢 "AI agents" / 第 1 頁 / 排名 2 的 U2，逐一照抄所有原始值，因此屬於匯出重複資料列。第 8 筆資料列使用同一個鍵，但其值為 U9。鍵 R1+bing+AI agents+1+2 對應的 U2 和 U9 均涉及衝突；請在衝突記錄表中保留這 2 個候選值，不要相信最先出現或佔多數的值。保留的數量為：8 筆原始資料列、1 筆匯出重複資料列、6 個觀測鍵、1 個有衝突的鍵、5 筆無衝突的觀測記錄，以及 4 個已接納的目標。U9 仍不列入已接納的目標。

*原創虛構的 8 筆原始資料列表。*

| RowId | RunId | Engine | ExecutedQuery | Page | RankOnPage | CanonicalUrl | ObservedAt |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | R1 | bing | AI agents | 1 | 1 | U1 | 2026-10-13T06:20:15Z |
| 2 | R1 | bing | AI agents | 1 | 2 | U2 | 2026-10-13T06:20:15Z |
| 3 | R1 | bing | small business automation | 1 | 1 | U2 | 2026-10-13T06:21:00Z |
| 4 | R1 | bing | small business automation | 1 | 2 | U3 | 2026-10-13T06:21:00Z |
| 5 | R2 | bing | AI agents | 1 | 1 | U1 | 2026-10-13T07:00:15Z |
| 6 | R2 | bing | AI agents | 1 | 2 | U4 | 2026-10-13T07:00:15Z |
| 7 | R1 | bing | AI agents | 1 | 2 | U2 | 2026-10-13T06:20:15Z |
| 8 | R1 | bing | AI agents | 1 | 2 | U9 | 2026-10-13T06:20:15Z |

*原創虛構的觀測鍵狀態表（共 6 個觀測鍵）。*

| ObservationKey | CandidateCanonicalUrl | 狀態 / 處理情況 |
| --- | --- | --- |
| R1+bing+AI agents+1+1 | U1 | 無衝突 |
| R1+bing+AI agents+1+2 | U2, U9 | 因衝突而暫緩處理（2 個候選值均保留待查；第 7 筆資料列為匯出重複情況的記錄） |
| R1+bing+small business automation+1+1 | U2 | 無衝突 |
| R1+bing+small business automation+1+2 | U3 | 無衝突 |
| R2+bing+AI agents+1+1 | U1 | 無衝突 |
| R2+bing+AI agents+1+2 | U4 | 無衝突 |

*原創虛構的目標參照表（4 個已接納的目標）。*

| TargetKey | 無衝突的觀測記錄參照 | 狀態 |
| --- | --- | --- |
| U1 | R1 AI agents 排名 1，R2 AI agents 排名 1 | 無衝突 |
| U2 | R1 small business automation 排名 1 | 無衝突（R1 AI agents 排名 2 的衝突記錄保留待查） |
| U3 | R1 small business automation 排名 2 | 無衝突 |
| U4 | R2 AI agents 排名 2 | 無衝突 |

*原創虛構的 CSV 測試資料，包含欄位內的換行、重複書寫的引號、Unicode 文字 café，以及含逗號的查詢：*

程式碼片段

```text
runId,engine,executedQuery,page,rankOnPage,title,canonicalUrl
"R1","bing","garden, tray",1,1,"Café guide
""Best picks""","https://example.com/garden"
```

虛構的合併記錄表與資料檢查

*測試資料解碼後的值與讀者檢查：*查詢欄位解碼後為 `garden, tray`；標題欄位解碼後為 `Café guide`，接着是 1 個實際換行，以及前後各有 1 個引號的 `Best picks`；canonicalUrl 解碼後是 `https://example.com/garden` 這個純字串，不含 Markdown 語法。讀者透過匯出再匯入的檢查，可確認逗號分隔、欄位內的換行、每組前後各 1 個引號，以及 Unicode 字元均獲正確保留。任何關於已完成 Python 解析、寫入或讀取的陳述，都只適用於這 1 組虛構測試資料，絕不適用於 Actor 匯出資料或大型資料集。

## 下一步

使用官方 [Google Search Scraper Actor](https://apify.com/chronometrica/google-search-scraper) 和 [Export Search Results to CSV Task](https://apify.com/chronometrica/google-search-scraper/examples/export-search-results-to-csv)，檢查你的資料收集設定，匯出原始 Bing 觀測記錄，並在移除重複網址前核對及處理記錄之間的差異。

## 來源與延伸閱讀

- [自動尋找可供擷取的網址](https://www.reddit.com/r/learnpython/comments/f96o07/automate_the_process_of_finding_urls_for_scraping/)