
當你深度使用 n8n 之後,你可能會遇到這樣的情境:你已經有一個用 Python 搭配 BeautifulSoup 和 Selenium 寫好的、功能極其強大的爬蟲腳本,它能處理複雜的登入、互動與反爬蟲機制;或者,你團隊的數據科學家提供了一段 Node.js 腳本,需要用到一些 n8n 預設環境中沒有的 NPM 套件。
這時,你是否會陷入兩難?難道要將這些已經穩定運行的外部腳本,全部用 n8n 的內建節點重寫一遍嗎?
答案是:完全不需要! n8n 提供了一個專為開發者與系統管理員設計的終極「後門」——Execute Command
節點。這個節點讓你能夠在 n8n 工作流的任何一個步驟,直接執行你伺服器上的任何 Shell 指令,其中就包括了呼叫你早已寫好的 Python 或 Node.js 腳本。
這項功能,讓 n8n 從一個自動化工具,蛻變為一個強大的「任務調度與整合平台 (Orchestration Platform)」。你的外部腳本負責攻堅克難的「核心任務」,而 n8n 則負責流程的觸發、排程、數據的傳遞與後續的跨系統整合。
這篇文章將是你的 n8n Execute Command
節點實戰指南。我們將深入探討為何要調用外部腳本,並手把手教你如何解決最關鍵的「數據交換」問題,最後透過一個完整的 Python 爬蟲實戰案例,讓你學會如何將你現有的程式碼資產,無縫整合進 n8n 的視覺化世界中。
為什麼不直接在 n8n 裡做?調用外部腳本的 3 大理由
在動手之前,我們先釐清為什麼要「捨近求遠」,使用外部腳本而不是 n8n 的內建節點。
- 重複利用現有程式碼資產 (Reusability): 你或你的團隊可能已經花費了大量時間,撰寫並測試了穩定可靠的爬蟲或數據處理腳本。
Execute Command
節點讓你可以直接「利舊」,將這些現有的程式碼作為一個「黑盒子」模組,直接插入到 n8n 流程中,無需重寫,最大化開發效率。 - 處理複雜的依賴與環境 (Complex Dependencies): n8n 的
Code
節點雖然方便,但其預設環境有限。如果你的 Python 爬蟲需要用到Pandas
,Selenium
或是Scrapy
這類大型函式庫,或者你的 Node.js 腳本依賴於某些需要編譯的 C++ 模組,在 n8n 的 Docker 環境中安裝這些依賴,會比在主機上直接設定來得複雜。直接呼叫一個在主機上已配置好完整環境的外部腳本,是更簡單直接的作法。 - 執行n8n 不擅長的高效能或底層任務: 對於需要大量運算、處理大型檔案、或是需要直接與伺服器檔案系統進行深度互動的任務,一個獨立的、經過最佳化的外部腳本,其執行效能與彈性,往往會優於在 n8n 的 JS 沙盒環境中執行。
環境準備:讓 n8n 能夠找到並執行你的腳本
重要前提: Execute Command
節點只能在自架設 (Self-Hosted) 的 n8n 實例中使用,因為它需要直接存取伺服器的 Shell 環境。n8n Cloud 版本基於安全考量,不提供此功能。
你的 n8n 實例與你的外部腳本,必須存在於同一個可以互相溝通的環境中。
- 對於 Docker 用戶 (推薦): 最好的做法是,建立一個客製化的 Docker Image。以 n8n 官方 Image 為基底,然後在
Dockerfile
中,加入安裝 Python/Node.js、相關函式庫 (pip install requests beautifulsoup4
) 以及複製你的腳本檔案 (COPY my_scraper.py /scripts/
) 的指令。這能確保你的 n8n 容器,是一個包含了所有執行條件的、可攜的獨立環境。 - 對於主機直接安裝用戶: 你需要確保執行 n8n 的使用者,擁有執行你 Python/Node.js 腳本的權限,並且所有相關的函式庫都已經在主機上安裝完成。
核心關鍵:n8n 與外部腳本的「數據交換」協議
這是整個流程中最需要技巧的部分:如何將 n8n 工作流中的動態數據(例如,要爬取的 URL)傳遞給你的 Python 腳本?又該如何將 Python 腳本的執行結果,回傳給 n8n 繼續使用?
答案是透過最古老也最可靠的 Shell 機制:命令列參數與標準輸出。
數據輸入 (n8n -> 腳本):使用命令列參數
我們可以在 Execute Command
節點的 Command
欄位中,使用 n8n Expressions,將工作流中的數據,作為參數附加在執行指令的後面。
- n8n
Execute Command
設定:python3 /path/to/your/scraper.py {{ $json.url }} {{ $json.keyword }}
- Python 腳本 (
scraper.py
) 中接收參數:Pythonimport sys # sys.argv 是一個列表,包含了所有命令列參數 # sys.argv[0] 是腳本名稱本身 # sys.argv[1] 是第一個參數,以此類推 target_url = sys.argv[1] target_keyword = sys.argv[2] print(f"準備爬取 URL: {target_url},尋找關鍵字: {target_keyword}")
數據輸出 (腳本 -> n8n):將結果以 JSON 格式印到 stdout
為了讓 n8n 能輕易地解析腳本的回傳結果,最佳實踐是讓你的腳本將最終的成果,以 JSON 字串的格式,「印 (print)」到標準輸出 (stdout) 上。n8n 會自動捕捉這段輸出。
- Python 腳本 (
scraper.py
) 中回傳結果:Pythonimport json # ... 爬蟲邏輯 ... result = { "title": "爬取到的網頁標題", "links_found": ["https://link1.com", "https://link2.com"] } # 將 Python 字典轉換成 JSON 字串,並印出 print(json.dumps(result))
- n8n 中接收與解析結果:
Execute Command
節點的輸出stdout
會是一個包含上述 JSON 字串的文字。我們需要再接一個Set
節點,使用JSON.parse()
函式將其轉回可用的 JSON 物件。- Set 節點 Value (Expression):
{{ JSON.parse($json.stdout) }}
- Set 節點 Value (Expression):

Python 爬蟲實戰:建立一個抓取網頁標題的 n8n 工作流
讓我們將以上概念串連起來。
目標: 建立一個 n8n 工作流,接收一個 URL 輸入,調用一個外部 Python 腳本來抓取該 URL 的網頁標題,並在 n8n 中取得這個標題。
步驟一:準備 Python 腳本 (title_scraper.py
)
在你的 n8n 伺服器上(或 Docker Image 中),建立一個 title_scraper.py
檔案:
Python
import sys
import json
import requests
from bs4 import BeautifulSoup
def get_title(url):
try:
response = requests.get(url)
response.raise_for_status() # 如果 HTTP 狀態碼不是 200,就拋出錯誤
soup = BeautifulSoup(response.text, 'html.parser')
# 準備回傳的結果
result = {
"success": True,
"url": url,
"title": soup.title.string if soup.title else "No Title Found"
}
except requests.exceptions.RequestException as e:
result = {
"success": False,
"url": url,
"error": str(e)
}
# 將結果以 JSON 格式印到 stdout
print(json.dumps(result, ensure_ascii=False))
if __name__ == "__main__":
if len(sys.argv) > 1:
target_url = sys.argv[1]
get_title(target_url)
步驟二:建立 n8n 工作流
流程設計: Start
-> Set (設定目標)
-> Execute Command
-> Set (解析結果)
Set
節點 (設定目標):- 建立一個
url_to_scrape
欄位,值為你想爬取的網址,例如https://www.ptt.cc/bbs/movie/index.html
。
- 建立一個
Execute Command
節點:- Command:
python3 /path/to/your/title_scraper.py {{ $json.url_to_scrape }}
(請將路徑換成你實際的腳本路徑)。
- Command:
Set
節點 (解析結果):- Keep Only Set: 啟用此選項,保持資料乾淨。
- Name:
scrape_result
- Value (Expression):
{{ JSON.parse($json.stdout) }}
執行後,你會在最後一個 Set
節點的輸出中,看到一個結構化的 scrape_result
物件,裡面包含了 success
, url
, 和 title
等欄位,你可以在後續流程中,輕鬆地取用 {{ $json.scrape_result.title }}
。
最佳實踐與安全注意事項
- 錯誤處理:
Execute Command
節點會回傳exitCode
和stderr
。你應該在節點後加上IF
節點,判斷exitCode
是否不為0
,或stderr
是否有內容。若有,則代表腳本執行失敗,應觸發錯誤通知流程。 - 安全性:
Execute Command
節點是一個極其強大的工具,也意味著潛在的安全風險。絕對不要將來自不可信賴的外部來源的數據(例如公開的 Webhook),直接、未經處理地拼接到你的 Shell 指令中,這可能導致「命令注入 (Command Injection)」攻擊。 - 管理依賴: 對於 Docker 用戶,最佳實踐是將所有
pip install
或npm install
指令,明確地寫在你的Dockerfile
中,而不是手動進入容器安裝。這確保了你的環境是可重複建置的。

結語
n8n 的 Execute Command
節點,是你現有程式碼資產與 n8n 視覺化世界之間的完美橋樑。它讓你不必為了自動化而拋棄你最熟悉、最擅長的程式語言與函式庫。
透過掌握「命令列參數傳入」與「stdout
JSON 傳出」這個核心的數據交換協議,你可以將任何複雜的外部腳本,都轉化為一個個功能強大、可被 n8n 輕鬆調度的「黑盒子」模組。這不僅大幅擴展了 n8n 的能力邊界,也讓你的自動化專案,能夠更緊密地與團隊現有的技術棧相結合。
更多精選文章請參考
n8n 與 Zapier 比較:該選哪個?2025年最完整功能、費用、優缺點分析
開源自動化工具推薦:從工作流程到測試,找到最適合你的免費方案
n8n 發送 Email 超詳細教學:從 SMTP 設定到 Gmail 節點串接,一篇搞定!
n8n Notion 串接終極指南:2025 年打造自動化工作流程,效率翻倍!