跳到正文

Puppeteer 轮换代理:按页面、上下文还是浏览器

先选好“谁来轮换”这个单位,再逐次检查出口 IP。

三种轮换方式

三种轮换方式
项目代理怎么设得到什么代价
每个代理一个上下文createBrowserContext({ proxyServer }) 加 page.authenticate每个上下文 cookie 和存储分开,只有一个浏览器进程要自己维护代理清单
每个代理一个浏览器启动时 --proxy-server(代理有账号密码就配合 proxy-chain)完全隔离,各一个进程每个代理多占内存
一个轮换网关一个 --proxy-server、一组登录每个新连接换一个 IP不用维护清单;不开会话时一个页面可能用到好几个 IP

依据 Puppeteer API 页面和 proxy-chain 说明(2026 年 11 月 13 日读取)以及 Proxy302 产品信息。

为什么没有“每页一个代理”

Puppeteer 参考文档把 proxyServer 列在浏览器上下文的选项里:该上下文所有请求用的代理。启动参数则作用于整个浏览器。页面一旦打开就不能换到另一个代理,所以能轮换的最小单位是上下文。

账号密码由 Page.authenticate 提供。Puppeteer 提示它会在背后开启请求拦截,可能影响性能,所以只在需要的页面上调用,并且放在首次跳转之前。

每个代理一个上下文

import puppeteer from 'puppeteer'

const proxies = [
  { server: 'http://HOST1:2222', username: 'LOGIN1', password: 'PASSWORD1' },
  { server: 'http://HOST2:2222', username: 'LOGIN2', password: 'PASSWORD2' },
]

const browser = await puppeteer.launch()
for (const p of proxies) {
  const context = await browser.createBrowserContext({ proxyServer: p.server })
  const page = await context.newPage()
  await page.authenticate({ username: p.username, password: p.password })
  await page.goto('https://ipinfo.io/json')
  console.log(await page.evaluate(() => document.body.innerText))
  await context.close()
}
await browser.close()

仅为示例。HOST、LOGIN、PASSWORD 换成“我的资产”里的值。每次运行会打印该代理的 IP 信息。

每个代理一个浏览器,配合 proxy-chain

想要每个代理独占一个浏览器时,启动参数能写 URL,但 Chrome 不会从里面取账号密码。proxy-chain 库会启动一个保存登录信息的小型本地代理,返回一个本地 URL 给 --proxy-server 用;浏览器用完后把它关掉。

Chrome 不支持任何 SOCKS5 认证方式,所以给浏览器的要是 HTTP 地址。

每个代理一个浏览器

import puppeteer from 'puppeteer'
import { anonymizeProxy, closeAnonymizedProxy } from 'proxy-chain'

const localUrl = await anonymizeProxy('http://LOGIN:PASSWORD@HOST:2222')
const browser = await puppeteer.launch({ args: [`--proxy-server=${localUrl}`] })
const page = await browser.newPage()
await page.goto('https://ipinfo.io/json')
console.log(await page.evaluate(() => document.body.innerText))
await browser.close()
await closeAnonymizedProxy(localUrl, true)

仅为示例。需要先 npm install puppeteer proxy-chain。HOST、LOGIN、PASSWORD 请替换。

一个轮换网关

用动态住宅流量时,只设一个代理:proxy.proxy302.com 的 HTTP 端口 2222,出口 IP 自己会变。不开会话时,每个新连接换一个 IP,复用的连接保持原 IP。一个页面会开好几个连接,所以同一页面的不同请求可能从不同 IP 出去。

页面必须用同一个 IP 的话,生成代理时开会话;低价线路在控制台有 10、30、60、120 分钟可选,也可以自己填 1 到 120 分钟。要固定几天的地址,就改用静态 IP。低价线路价格是 US$1.50 每 GB。

一个浏览器,一个网关

import puppeteer from 'puppeteer'

const browser = await puppeteer.launch({
  args: ['--proxy-server=http://proxy.proxy302.com:2222'],
})
for (let i = 0; i < 3; i++) {
  const page = await browser.newPage()
  await page.authenticate({ username: 'LOGIN', password: 'PASSWORD' })
  await page.goto('https://ipinfo.io/json')
  console.log(await page.evaluate(() => document.body.innerText))
  await page.close()
}
await browser.close()

仅为示例。LOGIN、PASSWORD 换成“我的资产”里的值。两个页面打印出同一个 IP,说明连接被复用了:下一个任务请换新的上下文或浏览器。

4 步选择并测试

  1. 第 1 步

    先想清楚哪些必须在一起。登录流程整个过程要同一个 IP:用每个代理一个上下文或浏览器,或者开会话。互不相关的页面抓取可以用网关。

  2. 第 2 步

    从“我的资产”复制主机、端口、用户名、密码,协议选 HTTP,因为 Chrome 没有 SOCKS5 登录。

  3. 第 3 步

    用两个代理或两次运行跑上面的某个例子,对比 ipinfo.io/json 里的 ip 字段。

    预期结果 不同上下文或不同运行得到不同 IP;同一个会话内 IP 相同。

  4. 第 4 步

    确认无误再加入真正的任务。遵守所访问网站的条款,请求频率保持合理。

轮换不起作用时

每个上下文打印的都是你自己的 IP

检查 页面是从上下文创建的,而不是从浏览器创建的吗?

处理 用 context.newPage(),并为每个上下文打印 ipinfo.io/json。

407 或者反复要求登录

检查 page.authenticate 必须在首次 goto 之前运行,且账号密码正确。

处理 从“我的资产”重新复制用户名和密码。

网关每个页面给同一个 IP

检查 复用的连接保持 IP,会话也会有意固定一个 IP。

处理 任务之间关闭上下文或浏览器,或者生成不带会话的代理。

停止条件 代理地址根本连不上的话,把订单号发给客服,不要继续轮换。

常见问题

Puppeteer 能给每个页面设不同代理吗?

已经打开的页面不行。代理在启动时按浏览器设置,或按浏览器上下文设置,最小单位是上下文。

代理的用户名和密码怎么传?

在首次跳转前调用 page.authenticate 传入用户名和密码,或者用 proxy-chain 把登录放在本地代理里。

轮换代理每个请求都换 IP 吗?

不是。每个新连接换一个 IP;复用的连接保持原 IP。

Puppeteer 里能用带账号密码的 SOCKS5 吗?

Chrome 里不行:它不支持任何 SOCKS5 认证方式。请用 HTTP 地址。

轮换用 Proxy302 的哪种产品?

要网关自动换 IP 就用动态住宅;每个任务需要固定地址,就用一批静态 ISP IP。

参考资料

5
  1. Puppeteer API:BrowserContextOptions

    官方文档 · 确认日期:

    2026 年 11 月 13 日读取:proxyServer 是该上下文所有请求使用的代理服务器(端口可选),账号密码用 Page.authenticate 设置;proxyBypassList 是不走代理的主机列表。

  2. Puppeteer API:Page.authenticate

    官方文档 · 确认日期:

    2026 年 11 月 13 日读取:为 HTTP 认证提供凭据;其背后会开启请求拦截,可能影响性能。

  3. proxy-chain 说明文档(apify/proxy-chain)

    外部网站资料 · 确认日期:

    2026 年 11 月 13 日读取:anonymizeProxy 启动一个本地开放代理,转发到带认证的 HTTP/HTTPS 代理并返回它的 URL;closeAnonymizedProxy 关闭它;示例用该本地 URL 作为 --proxy-server 启动 Puppeteer。

  4. Chromium 代理设置说明

    官方文档 · 确认日期:

    2026 年 11 月 13 日读取:Chrome 不支持任何 SOCKSv5 认证方式;--proxy-server 可写 http:// 或 socks5:// 这样的 URI。

  5. Proxy302 产品信息与价目表

    产品观察 · 确认日期:

    站点产品信息与线路说明,2026 年 11 月 10、11 日核对:动态住宅入口 proxy.proxy302.com,HTTP 端口 2222、SOCKS5 端口 3333;低价线路 US$1.50/GB;不开会话时每个新连接换一个 IP,复用(keep-alive)的连接 IP 不变;低价线路会话 1 至 120 分钟;静态 ISP IP 租期内不轮换。

准备好试试了吗?

注册账号、充值一次,就能选动态住宅、静态 ISP 或数据中心 IP,几分钟配进你的浏览器。