You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不重启已打开的Puppeteer浏览器的前提下动态切换代理?

Puppeteer动态切换代理(无需重启浏览器)

Puppeteer启动时传入的--proxy-server参数仅在浏览器进程初始化时读取生效,运行时修改对应变量无法触发代理配置更新,因此之前的方案不生效。


方案1:使用puppeteer-page-proxy库(页粒度代理,最简便)

这个库可以针对单个页面独立设置代理,不需要修改浏览器全局配置,切换代理只需重新调用设置方法即可,刷新页面就会生效。

安装依赖

npm install puppeteer-page-proxy

改造后的初始化代码

const useProxy = require('puppeteer-page-proxy');
var proxies = get_proxy() // 原有获取代理逻辑
var useragent = randomUseragent.getRandom()

let browser = await puppeteer.launch({ 
  headless: false,
  args: [
    // 可删除原有的--proxy-server启动参数
    `--user-agent="${useragent}"`,
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-infobars',
    '--window-position=0,0',
    '--ignore-certifcate-errors',
    '--ignore-certifcate-errors-spki-list'
  ]
})

let page = await browser.newPage()
// 初始化设置第一个代理
await useProxy(page, `http://${proxies.address}:${proxies.port}`)

代理封禁后的切换逻辑

const proxy_banned = await check_proxy_ban()

if(proxy_banned){
  // 拉取新的代理
  const newProxy = get_proxy()
  // 直接给当前页面设置新代理即可,无需重启浏览器
  await useProxy(page, `http://${newProxy.address}:${newProxy.port}`)
  // 刷新页面自动走新代理
  await page.reload()
  return
} else{
  return
}

如果你的代理需要身份验证,直接在代理地址里加认证信息即可:

await useProxy(page, `http://${username}:${password}@${newProxy.address}:${newProxy.port}`)

方案2:原生CDP实现(轻量化无额外UI依赖)

如果不想引入puppeteer-page-proxy,可以直接调用Chrome DevTools Protocol的Fetch域实现代理转发,核心是拦截所有页面请求,通过新代理发送后再返回给页面,需要先安装http/https代理请求依赖:

npm install http-proxy-agent https-proxy-agent

代理切换封装方法示例:

const HttpProxyAgent = require('http-proxy-agent');
const HttpsProxyAgent = require('https-proxy-agent');

// 切换代理的封装方法
async function setPageProxy(page, proxyHost, proxyPort) {
  const client = await page.createCDPSession()
  // 启用Fetch域,拦截所有请求
  await client.send('Fetch.enable', {
    patterns: [{ urlPattern: '*' }]
  })
  // 监听请求拦截事件,通过代理发送请求
  client.on('Fetch.requestPaused', async (e) => {
    const { requestId, request } = e
    try {
      const isHttps = request.url.startsWith('https')
      const fetchResponse = await fetch(request.url, {
        method: request.method,
        headers: request.headers,
        body: request.postData,
        agent: isHttps ? new HttpsProxyAgent(`http://${proxyHost}:${proxyPort}`) : new HttpProxyAgent(`http://${proxyHost}:${proxyPort}`)
      })
      const body = await fetchResponse.arrayBuffer()
      // 将代理请求的结果返回给页面
      await client.send('Fetch.fulfillRequest', {
        requestId,
        responseCode: fetchResponse.status,
        responseHeaders: Object.fromEntries(fetchResponse.headers.entries()),
        body: Buffer.from(body).toString('base64')
      })
    } catch (err) {
      await client.send('Fetch.failRequest', {
        requestId,
        errorReason: 'Failed'
      })
    }
  })
}

内容的提问来源于stack exchange,提问作者Sean Berrie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:09:03