使用代理启动并进行身份验证#
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
headless: true,
args: ["--proxy-server=http://res.proxshift.com:9000", "--no-first-run"],
});
const page = await browser.newPage();
await page.authenticate({ username: "USER-cc-us-sid-run1-ttl-30m", password: "PASS" });
await page.goto("https://api.ipify.org", { waitUntil: "domcontentloaded", timeout: 45000 });
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();每次打开页面后,都要在首次导航前调用 page.authenticate;Chrome 会按页面请求代理凭据。用户名中包含国家/地区和会话 ID,因此在设定的有效期内,整个浏览器都会使用同一个家庭住宅出口。
每个浏览器使用一个代理#
Chrome 会将 --proxy-server 应用于整个浏览器实例。若需要多个国家/地区或会话,请运行多个浏览器(无头模式的开销很低),或建立 puppeteer.launch 工作池,让每个 worker 持有一个会话 ID。声称支持按页面代理的库会插入本地转发器;每个会话使用一个浏览器更为简单。
屏蔽图片、字体和媒体#
await page.setRequestInterception(true);
page.on("request", (req) => {
const t = req.resourceType();
if (["image", "media", "font", "stylesheet"].includes(t)) return req.abort();
req.continue();
});保持环境一致#
- 将
Accept-Language和时区设为出口所在国家/地区:使用page.setExtraHTTPHeaders({\"Accept-Language\": \"de-DE,de;q=0.9\"})和page.emulateTimezone(\"Europe/Berlin\")。 - 在启动参数中加入
--force-webrtc-ip-handling-policy=disable_non_proxied_udp,防止 WebRTC 泄漏。 - 每个账号使用一个浏览器;若账号需要表现为曾经访问过的设备,请复用其用户数据目录。
常见错误#
| 现象 | 原因 | 解决方法 |
|---|---|---|
| net::ERR_TUNNEL_CONNECTION_FAILED | 网关拒绝 CONNECT:凭据或参数错误,或没有可用出口 | 使用 cURL -v 重现问题并读取网关状态码 |
| net::ERR_PROXY_AUTH_UNSUPPORTED / 弹出提示 | 在导航后才调用 authenticate() | 在 goto 前调用 page.authenticate |
| 每个浏览器都显示相同 IP | 重复使用了同一个会话 ID | 每个浏览器使用不同的 -sid-,或将其省略 |
| 首次加载非常慢 | 家庭住宅出口加上资源繁重的页面 | 屏蔽资源;将超时提高至 45 秒 |
大家常问的问题#
Puppeteer 可以使用带密码的 SOCKS5 吗?
Chrome 不支持 SOCKS5 身份验证。请配合 page.authenticate 使用 9000 端口的 HTTP 代理,或将服务器 IP 加入白名单,并传入 --proxy-server=socks5://res.proxshift.com:9001。