
你是否在使用 n8n 爬蟲時,遇到了讓你束手無策的終極挑戰?你已經學會了如何使用 Browserless
節點來渲染 JavaScript 動態網站,成功抓取到頁面上的初始內容。但你很快就發現,真正的寶藏,往往隱藏在使用者互動之後。
- 你想抓取的完整評論列表,需要不斷點擊「載入更多」按鈕才會全部出現。
- 關鍵的內部資料,必須先在一個登入表單中輸入帳號密碼,才能看到。
- 你想追蹤的社群貼文,位於一個採用「無限滾動 (Infinite Scroll)」設計的頁面上,你需要像真人一樣不斷向下捲動,內容才會持續載入。
這些需要「互動」才能取得的資料,已經超越了一般爬蟲工具的能力範圍。這時,你需要的不僅僅是一個能「看見」網頁的瀏覽器,更需要一雙能「操作」網頁的無形之手。這雙手,就是 Puppeteer。
Puppeteer 是一個由 Google Chrome 團隊開發的 Node.js 函式庫,它能讓你透過程式碼,來控制一個完整的 Chrome/Chromium 瀏覽器。而當你將 Puppeteer 的強大互動能力,與 n8n 的視覺化工作流結合時,你就擁有了一套無所不能的終極瀏覽器自動化武器。
這篇文章將是你的 n8n Puppeteer 進階實戰指南。我們將教你如何活用 Browserless
節點來執行 Puppeteer 腳本,並提供三個超實用的程式碼範例,帶你從零開始,解決點擊按鈕、填寫表單,甚至是處理最棘手的無限滾動頁面。
當「看見」還不夠:為什麼你需要 Puppeteer 來「互動」?
在我們的上一篇 n8n Browserless 教學 中,我們學會了使用 Get Content
操作來解決 JavaScript 的渲染問題。這相當於讓 n8n 擁有了「看見」網頁最終樣貌的能力。
然而,許多網頁的內容,並不是在一開始就全部載入的。它們需要使用者的互動來觸發:
- 點擊 (Click): 點擊分頁、打開折疊面板、載入更多內容。
- 輸入 (Type): 在搜尋框或登入表單中輸入文字。
- 滾動 (Scroll): 向下滾動頁面來觸發下一頁內容的載入。
Puppeteer 的核心價值,就是賦予你的 n8n 工作流,一個能夠模擬所有這些真人互動行為的程式化介面,讓你的爬蟲從一個被動的「觀察者」,進化成一個主動的「操作者」。
準備你的 n8n Puppeteer 環境:活用 Browserless
節點
在 n8n 中執行 Puppeteer 腳本,最簡單、最推薦的方式,就是利用我們已經熟悉的 Browserless
節點。
Browserless
服務的後端,本身就是基於 Puppeteer 來驅動的。因此,它提供了一個完美的沙盒環境,讓我們可以安全地執行自訂的 Puppeteer 程式碼。
操作模式: 在 Browserless
節點中,我們需要將 Operation
設定為 Run Custom Function
。這個模式會提供一個程式碼編輯器,讓你可以在其中撰寫並執行一段 Puppeteer 腳本。
Puppeteer 核心指令速查:page
物件的常用方法
在 Run Custom Function
模式的程式碼中,你會得到一個名為 page
的核心物件,它代表了瀏覽器當前的分頁。所有互動,都是透過呼叫 page
物件的方法來完成的。
以下是我們在本次教學中會用到的幾個關鍵方法:
page.goto(url)
: 前往指定的網址。page.waitForSelector(selector)
: 等待,直到頁面上出現符合指定 CSS Selector 的元素。這是確保頁面元素已載入完成的關鍵指令。page.click(selector)
: 模擬滑鼠點擊符合指定 CSS Selector 的元素。page.type(selector, text)
: 在符合指定 CSS Selector 的輸入框中,模擬鍵盤輸入文字。page.evaluate(func)
: 在瀏覽器的上下文中執行一段 JavaScript 函式。這是我們用來滾動頁面或從頁面中提取資料的核心方法。page.content()
: 獲取當前頁面完整渲染後的 HTML 內容。
實戰演練一:自動點擊「載入更多」按鈕,抓取完整列表
- 目標: 某個新聞網站的文章列表,一次只顯示 10 篇,需要點擊 5 次「載入更多」按鈕,才能看到全部 60 篇的內容。
- 流程設計:
Start
->Browserless (Run Custom Function)
->HTML Extract
Browserless
節點的 Run Custom Function
程式碼:
JavaScript
// page 是 n8n 傳入的 Puppeteer 頁面物件
// context 則包含了一些額外資訊
// 1. 前往目標網址
await page.goto('https://example.com/news');
// 2. 我們要重複點擊 5 次
const clicks = 5;
for (let i = 0; i < clicks; i++) {
try {
// 等待「載入更多」按鈕出現
await page.waitForSelector('#load-more-button', { timeout: 5000 });
// 點擊按鈕
await page.click('#load-more-button');
// 點擊後,最好稍微等待一下,讓新內容有時間載入
await page.waitForTimeout(1000); // 等待 1 秒
} catch (error) {
// 如果按鈕找不到了(可能已經是最後一頁),就跳出迴圈
console.log('Load more button not found. Assuming end of content.');
break;
}
}
// 3. 當所有內容都載入後,回傳最終的 HTML
const finalHtml = await page.content();
return {
html: finalHtml
};
這個節點的輸出,就會是一個包含了全部 60 篇文章的完整 HTML,你可以將它直接交給 HTML Extract
節點進行後續的資料提取。

實戰演練二:自動化登入與表單填寫
- 目標: 自動登入一個需要帳號密碼的網站後台,並抓取登入後才能看到的會員資料。
- 流程設計:
Start
->Browserless
->HTML Extract
Browserless
節點的 Run Custom Function
程式碼:
JavaScript
// 1. 前往登入頁面
await page.goto('https://example.com/login');
// 2. 等待表單元素出現
await page.waitForSelector('input[name="username"]');
await page.waitForSelector('input[name="password"]');
await page.waitForSelector('button[type="submit"]');
// 3. 填寫表單
// 建議將帳號密碼存在 n8n 的 Credential 中,再透過 context 傳入
// 為了簡化範例,這裡我們先寫死
await page.type('input[name="username"]', 'my_username');
await page.type('input[name="password"]', 'my_secret_password');
// 4. 點擊登入按鈕,並等待頁面跳轉完成
await Promise.all([
page.click('button[type="submit"]'),
page.waitForNavigation(),
]);
// 5. 現在我們已經在登入後的頁面了,回傳其 HTML
const memberPageHtml = await page.content();
return {
html: memberPageHtml
};
終極挑戰:如何用 Puppeteer 處理「無限滾動 (Infinite Scroll)」頁面?
這是最棘手的爬蟲情境之一,因為它沒有一個可以點擊的「下一頁」或「載入更多」按鈕。
- 目標: 抓取一個採用無限滾動的社群媒體頁面的所有貼文。
- 策略: 我們需要寫一個迴圈,在迴圈中不斷地將頁面滾動到最底部。每次滾動後,比較滾動前後的頁面高度。如果高度不再增加,就代表已經沒有新的內容可以載入了,此時就可以跳出迴圈。
Browserless
節點的 Run Custom Function
程式碼:
JavaScript
await page.goto('https://example.com/infinite-scroll-feed');
let previousHeight;
while (true) {
// 使用 page.evaluate 在瀏覽器中執行 JavaScript 來取得頁面高度
const currentHeight = await page.evaluate('document.body.scrollHeight');
// 如果目前高度與前一次相同,代表已經到底部,跳出迴圈
if (currentHeight === previousHeight) {
break;
}
// 滾動到頁面底部
await page.evaluate('window.scrollTo(0, document.body.scrollHeight)');
// 等待新內容載入
await page.waitForTimeout(2000); // 等待 2 秒
// 更新前一次的高度
previousHeight = currentHeight;
}
const fullHtml = await page.content();
return {
html: fullHtml
};
Puppeteer 自動化最佳實踐與除錯技巧
waitForSelector
是你的摯友: 在進行任何click
或type
操作前,永遠先用waitForSelector
來確保該元素已經存在於頁面上。這可以避免 90% 因為頁面載入速度不一而導致的「找不到元素」錯誤。- 善用
console.log
: 你可以在 Puppeteer 腳本中使用console.log()
。這些日誌會顯示在 n8n 的執行日誌中,是你除錯時觀察變數或流程狀態的好幫手。 - 負責任的爬取: 每次互動後,都加入適當的
page.waitForTimeout()
等待時間,模擬真人的操作間隔。這不僅能提高成功率,也是對目標網站伺服器資源的尊重。

結語
n8n 與 Puppeteer (透過 Browserless 節點) 的結合,為自動化爬蟲帶來了終極的解決方案。它讓你的爬蟲不再只是一個被動的 HTML 下載器,而是一個能夠深度與網頁互動、模擬複雜真人行為的智慧代理。
雖然撰寫 Puppeteer 腳本需要一些基礎的 JavaScript 知識,但正如你所見,幾個核心的指令,就能解鎖點擊、填表、無限滾動等無比強大的能力。當你下一次遇到任何無法用靜態方式抓取的頑固網站時,別忘了你工具箱中還藏著這把削鐵如泥的瑞士刀。
更多精選文章請參考
n8n 與 Zapier 比較:該選哪個?2025年最完整功能、費用、優缺點分析
開源自動化工具推薦:從工作流程到測試,找到最適合你的免費方案
n8n 發送 Email 超詳細教學:從 SMTP 設定到 Gmail 節點串接,一篇搞定!
n8n Notion 串接終極指南:2025 年打造自動化工作流程,效率翻倍!