Socks5Proxy

Puppeteer代理設定:以--proxy-server與page.authenticate連接

本指南說明Puppeteer啟動Chrome時,透過--proxy-server參數與page.authenticate驗證連接Socks5Proxy的HTTP代理,以及SOCKS5連接、多IP瀏覽器分流的實作程式碼。

Puppeteer的代理如何運作?

Puppeteer透過Chrome啟動參數設定代理。--proxy-server填入地址後,該瀏覽器所有頁面將共用代理。HTTP代理帳密無法透過參數傳遞,需在頁面開啟後以page.authenticate傳送,Puppeteer會自動回應代理認證請求。

範例使用 IP 198.51.100.23,HTTP 端口 8000,SOCKS5 端口 1080,帳號 spx_user,密碼 spx_pass。

npm install puppeteer

如何連接 HTTP 代理並驗證?

在 launch 的 args 中加入 --proxy-server=198.51.100.23:8000,並在 newPage 建立頁面後立即透過 page.authenticate 傳入帳號密碼。由於每個頁面都需要重新驗證,因此每次建立新頁面時都需重複此操作。

HTTPS 網站可正常開啟。瀏覽器會建立 CONNECT 隧道進行加密通訊。

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  headless: true,
  args: ["--proxy-server=http://198.51.100.23:8000"],
});

const page = await browser.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });

await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded" });
console.log(await page.evaluate(() => document.body.innerText)); // proxy IP

await browser.close();

如何使用 SOCKS5 代理?

在 --proxy-server 填入 socks5:// 地址即可。但 Chrome 不支援 SOCKS 代理的帳號密碼驗證,因此 page.authenticate 不適用於 SOCKS5。若需使用 SOCKS5 連線,請在儀表板設定執行此程式碼的伺服器 IPv4 進行 IP 授權。

若環境強制要求帳號密碼連接,最簡單方式是使用同 IP 的 HTTP 端口。因 IP 相同,目標網站識別的位置一致。

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
  args: ["--proxy-server=socks5://198.51.100.23:1080"], // server IP is authorized in the dashboard
});
const page = await browser.newPage();
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();

如何讓不同瀏覽器使用不同IP同時運作?

Chrome 每個瀏覽器實例只能使用一個代理,如需不同 IP 需分別啟動瀏覽器。以下程式碼示範透過 API 獲取 ip:port:user:pass 列表後,用前三個分別開啟瀏覽器並顯示各頁面 IP。

同時開啟過多瀏覽器會佔用大量記憶體。建議建立工作佇列並設定同時執行數量上限。

import puppeteer from "puppeteer";

const KEY = "YOUR_API_KEY";
const res = await fetch("https://socks5proxy.io/api/v1/proxies/download?format=ip:port:user:pass&protocol=http", {
  headers: { Authorization: "Bearer " + KEY },
});
const lines = (await res.text()).trim().split("\n").slice(0, 3);

await Promise.all(lines.map(async (line) => {
  const [ip, port, user, pass] = line.trim().split(":");
  const browser = await puppeteer.launch({ args: ["--proxy-server=http://" + ip + ":" + port] });
  try {
    const page = await browser.newPage();
    await page.authenticate({ username: user, password: pass });
    await page.goto("https://api.ipify.org", { timeout: 30000 });
    console.log(ip, await page.evaluate(() => document.body.innerText));
  } finally {
    await browser.close();
  }
}));

如何讓頁面開啟得更快?

經代理傳輸的圖片、字型、影片都會消耗頻寬與時間。若僅需文字數據,可用 page.setRequestInterception 攔截非必要請求,既能加速採集,也能節省共享方案的每月頻寬額度。

waitUntil 參數也很重要。networkidle0 會等待所有請求完成,可能導致速度較慢,建議改用 page.waitForSelector 在所需元素出現後立即進行下一步操作。

await page.setRequestInterception(true);
page.on("request", (req) => {
  const type = req.resourceType();
  if (type === "image" || type === "font" || type === "media") req.abort();
  else req.continue();
});

單一瀏覽器能否每個分頁使用不同IP?

Chrome 的 --proxy-server 參數會套用至整個瀏覽器,難以實現分頁不同 IP。Puppeteer 22+ 可透過 browser.createBrowserContext 的 proxyServer 選項為每個上下文設定獨立代理,且上下文間 cookie 與儲存完全隔離,適合帳號分離操作。

透過page.authenticate傳遞帳密即可在上下文建立的頁面中使用,相較開啟多個瀏覽器更節省記憶體。

import puppeteer from "puppeteer";

const browser = await puppeteer.launch();
const context = await browser.createBrowserContext({ proxyServer: "http://198.51.100.23:8000" });
const page = await context.newPage();
await page.authenticate({ username: "spx_user", password: "spx_pass" });
await page.goto("https://api.ipify.org");
console.log(await page.evaluate(() => document.body.innerText));
await context.close();
await browser.close();

要像該國用戶一樣,需要調整哪些設定?

根據 IP 國家,使用 page.setExtraHTTPHeaders 設定 Accept-Language,並使用 page.emulateTimezone 設定時區。若語言與時區與 IP 國家不同,頁面可能顯示錯誤語言或日期格式。

畫面大小可用page.setViewport設定,若需要手機畫面可將puppeteer的KnownDevices裝置設定傳入page.emulate。

await page.setExtraHTTPHeaders({ "Accept-Language": "ja-JP,ja;q=0.9" });
await page.emulateTimezone("Asia/Tokyo");
await page.setViewport({ width: 1366, height: 900 });

如何讓長時間運行的爬蟲保持瀏覽器穩定?

長時間運行的任務建議定期關閉並重新啟動瀏覽器,而不是一直保持開啟。長時間開啟的瀏覽器會逐漸占用更多記憶體,一旦出現錯誤,後續任務可能全部停止。

每個頁面都應使用 try 和 finally 確保 page.close 被調用,並在 goto 中加入 timeout 以避免在無回應的頁面上卡住。失敗的任務可以開啟新的瀏覽器並使用其他代理重新嘗試。

記錄各代理的響應時間與錯誤率,有助於找出慢速節點並聯繫儀表板客服,或調整任務分配方式。

如何解決常見錯誤?

若出現 net::ERR_INVALID_AUTH_CREDENTIALS 或 407 錯誤,可能是 page.authenticate 值錯誤或未在 newPage 後呼叫。請確認是否在每個頁面的 goto 前呼叫此方法。

net::ERR_PROXY_CONNECTION_FAILED 表示地址或端口錯誤。請確認 HTTP 地址是否使用 HTTP 端口,SOCKS5 地址是否使用 SOCKS5 端口。若 SOCKS5 連線被拒絕,請檢查伺服器出口 IP 是否已加入 IP 授權清單。

Puppeteer代理設定:page.authenticate認證 | Socks5Proxy