時鐘、收集卡片、成功閘門與儲存堆疊組成一條相連的工作流程。
可靠的工作流程會先檢查該次執行,然後才儲存各列。

本指南提供一個參考方法,供你在本地建立並測試,從而建立可重複的擷取工作流程,而不是預先建好的匯入,亦不是已驗證的完整部署。檢查點是已儲存的執行進度紀錄;upsert 是一項資料庫操作,會插入新列,或在唯一鍵重複相符時更新現有紀錄。

技術範圍與操作限制

在設定 n8n 工作流程之前,你必須了解這條擷取管道處理甚麼,以及其界限在哪裏。此系統只專注於自動資料擷取與持久儲存。它不會進行垃圾訊息篩選、情緒分析、客戶意圖評分、自動回覆或內容審核。如果你需要把留言歸入自訂類別,請閱讀我們的指南:Facebook 留言客戶意見分析。如果你需要把支援問題轉到使用中的服務台,請查看我們的教學:Facebook 未回覆留言問題佇列。

本教學說明如何用標準 n8n 節點,以及 Facebook Comments Scraper 的 HTTP API 作技術實作。API(應用程式介面,Application Programming Interface)是一組規則與端點,讓不同軟件程式透過網絡互相通訊。此擷取工具接受指定且已知的公開帖文 URL 作為輸入。它不接受一般個人檔案連結、群組 URL 或品牌頻道頁面。執行時,擷取工具會回傳扁平的資料紀錄,格式為 JSON(JavaScript 物件表示法,JavaScript Object Notation),這是用來分享結構化資料的標準文字格式。

每一輸出列代表一則頂層留言,或一則直接的巢狀回覆。回傳的承載資料包含字串識別碼,例如 commentId 與 contentId。請注意,authorId 與 publishedAt 可以是 null;publishedAt 與 scrapedAt 是時間戳記;isReply 是布林值,而不是精確的字串識別碼。原始 JSON 物件會保留 parentCommentId、rootCommentId、isReply、text 以及 null 值。在各次執行之間,你的資料庫會用 contentId 與 commentId 上的複合唯一限制去除重複,並以參數化查詢實作。

設定管道時,請記住以下操作參數:

  • 目標連結:你必須把 1 至 100 個明確的公開帖文 URL,作為字串項目放在一個陣列內。
  • 結果上限:參數 maxResultsPerPost 設定每則帖文最多收集多少列留言與回覆。把此參數設為 25,會把該次執行限制為每則帖文最多 25 列。
  • 回覆擷取:把 includeReplies 設為 true,即指示擷取工具在收集父留言的同時收集巢狀回覆。
  • 完整擷取:把 collectAllAvailable 設為 true 會略過數字結果上限,但仍受平台可見度限制與運算收費約束。
  • 排序參數:all、newest 或 most_relevant 等排序選項,決定 Facebook 在擷取前如何排列留言,並且獨立於結果上限運作。

核心 API 端點參考

下表摘要此工作流程所用的端點,以及其原始 URL 結構與預期的回應欄位:

核心 API 端點參考
端點 URL說明預期回應欄位
https://api.apify.com/v2/acts/chronometrica~facebook-comments-scraper/runs啟動擷取工具的執行data.id, data.defaultDatasetId, data.defaultKeyValueStoreId, data.status
https://api.apify.com/v2/actor-runs/RUN_ID檢查執行狀態data.status
https://api.apify.com/v2/datasets/DATASET_ID/items?format=json&clean=false&offset=0&limit=100取得資料集項目的分頁留言紀錄的 JSON 陣列
https://api.apify.com/v2/key-value-stores/STORE_ID/records/OUTPUT檢視該次執行的摘要儲存該次執行專用的摘要紀錄

注意:請把 RUN_ID、DATASET_ID 與 STORE_ID 等佔位符,換成你實際儲存的執行值。切勿把存取權杖直接寫入 URL 字串。

逐步架構與節點順序

要在 n8n 建立這條管道,你會設定一連串內建節點的結構化順序。你需要已安裝的 n8n、存放在 n8n Header Auth 憑證中的 Apify API 權杖(名稱為 Authorization,值為 Bearer your_token),以及一個關聯式資料庫憑證(例如 Postgres)。

1. 觸發條件與憑證設定

先在 n8n 建立新的工作流程。開啟工作流程設定,選取你的本地時區,並在建立與測試元件期間,讓工作流程保持未發佈。

你會建立兩個進入點:

  • Schedule Trigger:按你的時區設定,自動觸發每日或每小時的重複收集執行。
  • 手動觸發與復原輸入:供操作人員使用的獨立手動進入點。因為手動觸發不能直接接受執行 ID,請在其後放置一個 Edit Fields 節點,讓操作人員輸入已儲存的現有執行 ID。這樣你可以復原停滯的執行,而無需啟動新的擷取工作。

2. 啟動擷取工具

把排程觸發連接到名為 Launch Scraper 的 HTTP Request 節點。把方法設為 POST,並指向 Apify actor 執行端點。附上你的 Header Auth 憑證。用原始 URL 字串設定一個簡短的純 JSON 請求主體:

text
{
  "startUrls": [
    "https://www.facebook.com/story.php?story_fbid=123456789&id=987654321"
  ],
  "maxResultsPerPost": 25,
  "includeReplies": true,
  "collectAllAvailable": false,
  "commentSortMode": "all"
}
逐步架構與節點順序

當此請求成功時,Apify API 會回傳一個包含執行中繼資料的封套。你的工作流程必須立即擷取並儲存四個值:data.id、data.defaultDatasetId、data.defaultKeyValueStoreId 與 data.status。

把這些值存入以執行 ID 為鍵的可持久資料庫檢查點,並把嘗試次數初始化為 0,下一個偏移量初始化為 0。可持久是指永久儲存在關聯式資料庫中,而不是暫存在工作流程記憶體內。

關鍵安全規則:如果發生網絡逾時,切勿自動重試一次結果不明的啟動 POST 請求。如果第一個請求已到達伺服器,盲目重試會啟動第二次會計費的擷取執行。如果某次啟動結果不明,請先手動查看你的 Apify 帳戶執行清單,然後才觸發新的一次。

3. 復原路徑

如果某次執行失敗或停滯,手動復原分支會用操作人員提供的執行 ID 選取現有的檢查點紀錄,並完全跳過啟動節點。

你的工作流程強制規定:每個執行 ID 只可有一個進行中的執行。如果復原的執行在資料庫中已顯示終端已儲存狀態 SUCCEEDED,工作流程會完全跳過狀態輪詢,並直接前往分頁載入。如果已儲存狀態是 failed,則轉往手動覆核。其他狀態會進入有界限的輪詢。復原執行永不自動重設嘗試次數。

4. 狀態輪詢與計數閘門

每次檢查狀態之前,工作流程會查詢資料庫,以檢查目前的嘗試次數。如果嘗試次數已達 30,系統會把執行轉到手動覆核分支,以防止無限迴圈。

如果次數低於 30,工作流程會在資料庫中遞增嘗試次數,用 Wait 節點暫停執行 10 秒,然後用 HTTP GET 請求向 Apify API 檢查執行狀態(https://api.apify.com/v2/actor-runs/RUN_ID)。

輪詢期間的網絡請求錯誤,應使用有界限的讀取重試(最多 3 次嘗試,每次等待 10 秒),而不是重試 POST 請求。

工作流程會評估回傳的狀態:

  • SUCCEEDED:工作流程把該扁平狀態儲存到資料庫,並繼續取得資料集。
  • READY / RUNNING / ABORTING / TIMING-OUT:工作流程把執行轉回計數閘門,以便等待並再次檢查。
  • FAILED / ABORTED / TIMED-OUT:工作流程記錄失敗狀態,然後停止或轉往手動覆核。
  • 未知狀態:轉往手動覆核。

注意:停止輪詢迴圈並不會取消遠端的 Apify actor;它只是讓你的 n8n 工作流程停止等待。輪詢逾時並不表示該帖文有 0 則留言。

5. 分頁與頁面載入

一旦該次執行成功,工作流程便進入分頁迴圈。在取得每一頁之前,它會從資料庫重新載入目前的檢查點狀態,以取得最新的偏移量與資料集 ID。

它會發出 HTTP GET 請求以取得資料集項目(https://api.apify.com/v2/datasets/DATASET_ID/items?format=json&clean=false&offset=0&limit=100,代入目前的偏移量與已儲存的資料集 ID)。你必須指向該次執行專用的資料集 ID,而不是泛用的 latest 別名。把請求格式設為 JSON,使用 clean=false,並設定 limit=100。

設定 HTTP 節點回傳完整的回應主體。在把資料傳給任何分割節點之前,先記錄傳入陣列的長度。如果第一頁的陣列完全是空的,請略過分割,並透過專用端點(https://api.apify.com/v2/key-value-stores/STORE_ID/records/OUTPUT)用已儲存的儲存區 ID 檢查鍵值儲存的輸出紀錄,以判斷是否發生錯誤。對於其後的頁面,空陣列只是表示收集已結束。

6. 分割與資料庫 upsert

把資料集陣列傳入 Split Out 節點,並設定明確的目的地欄位,名稱為 comment。

下游的資料庫儲存節點會接收每個已分割的項目,並直接從 comment 對應欄位。它會驗證非空的字串識別碼與有效的時間戳記是否存在。它會對複合唯一鍵限制(contentId 與 commentId)執行使用參數化查詢的 upsert 操作。upsert 會插入新列,或在出現重複相符時更新現有紀錄。

為避免舊資料覆寫較新的更新,請設定資料庫更新條件,使傳入的文字與中繼資料只在傳入的 scrapedAt 時間戳記大於或等於已儲存的時間戳記時才更新。這代表該公開帖文最新被觀察到的狀態,而不是不可變更的歷史稽核紀錄,亦不是刪除證明。

7. 推進檢查點

當目前頁面的每個項目都成功寫入資料庫之後,工作流程會把資料庫中的檢查點偏移量加上 100。

關鍵規則:切勿按每則留言推進一次檢查點偏移量。你必須在整批成功之後,按每一頁剛好更新一次檢查點偏移量。如果資料庫寫入在一頁中途失敗,檢查點偏移量會保持不變,讓工作流程可以安全地重播該頁,而不會建立重複紀錄。

在分割步驟與資料庫步驟之間,另行保留目前頁面長度的中繼資料。最終檢查使用的是目前頁面的長度,而不是第一次迴圈的長度。如果目前頁面長度少於 100 個項目,收集便已完成,工作流程結束。如果頁面長度等於 100,工作流程會回到重新載入檢查點,並取得下一批。

讀者測試與驗證程序

在把工作流程發佈為於正式環境自動執行之前,你必須在本地建立並測試工作流程,並使用有結構的驗證檢查。不要依賴未經測試的範本。

  1. 獨立擷取測試:把凍結的測試案例輸入 {body: [25 comments]} 直接注入一個 Split Out 節點。該節點接到你的資料庫節點,並設定為立即 STOP,略過所有即時的檢查點節點與頁面摘要節點。驗證資料庫剛好儲存 25 列。第二次執行完全相同的測試案例,結果是插入 0 列新紀錄,現有紀錄會被評估,且沒有倒退。加入一筆不同的第 26 筆紀錄,會剛好插入 1 列新紀錄。此外,驗證較舊的測試案例不能覆寫較新的文字。
  2. 分頁測試案例:用一個以替身模擬的檢查點,以及分佈在 3 頁的 201 筆紀錄(分別為 100、100 與 1),測試你的偏移量迴圈,且不產生任何須付費的 Actor 呼叫。
  3. 容錯與輪詢測試:測試在輪詢路徑上,輪詢次數達到上限時會正確觸發手動覆核。模擬中間某一頁的資料庫寫入失敗。驗證檢查點偏移量保持不變、復原不會重新啟動擷取工具,以及非成功狀態會正確阻止取得資料集。
  4. 即時手動驗證:對一條真實的公開帖文連結執行一次手動測試。檢視你的平台限制、運算費用與執行日誌。

只有在所有本地測試都通過,而且排程時區已正確設定之後,你才應儲存並發佈你的 n8n 工作流程。

來源與延伸閱讀

作者 Chronometrica · 更新日期

返回頂端 ↑