@extra/proxy-router

中文文档
3.1.6发布于 2023/03/01MITTypeScriptESM + CJS近 30 天下载 15.5万

用于剧作家和傀儡的插件,用于动态路由代理.

中文使用文档
文档目录15 节
  1. 安装
  2. 兼容性
  3. 特征
  4. 使用量
  5. 简单
  6. 动态路由
  7. 进口
  8. 除错日志
  9. 如何运作
  10. API 密码
  11. 选项
  12. 替代品
  13. 代理. pace 文件 参考文献
  14. 用于木偶机的各种“ 每页代理” 插件
  15. 许可证

@ extra/ 代理路由器 GitHub Workflow Status Discord npm

用于 剧作家外出 财务报告和审定财务报表 木偶外传 用于动态路由.

安装

yarn add @extra/proxy-router
# - or -
npm install @extra/proxy-router
剧作家

如果这是你第一次 剧作家外出 插件这里的所有您需要的 :

yarn add playwright playwright-extra @extra/proxy-router
# - or -
npm install playwright playwright-extra @extra/proxy-router
傀儡

如果这是你第一次 木偶外传 插件这里的所有您需要的 :

yarn add puppeteer puppeteer-extra @extra/proxy-router
# - or -
npm install puppeteer puppeteer-extra @extra/proxy-router

兼容性

💫Chrome
铬
Chrome
颜色
Firefox
火花
Webkit
维基文库
剧作家外出✅✅✅✅
木偶外传✅✅🕒- 说吧
无头头发射连接
✅✅✅✅ (当地)

特征

插件使浏览器中使用代理更方便:

  • 处理代理认证
  • 可使用多个代理
  • 使用主机/域的灵活代理路由
  • 浏览器启动后动态更改代理
  • 每个代理或主机收集流量统计
  • 使用本地浏览器特性, 不丢失性能

使用量

用木偶吗? 要使用以下剧作家示例,只需更改您的 进口

简单

所有浏览器连接的单一代理

// playwright-extra is a drop-in replacement for playwright,
// it augments the installed playwright with plugin functionality
// Note: Instead of chromium you can use firefox and webkit as well.
const { chromium } = require('playwright-extra')

// Configure and add the proxy router plugin with a default proxy
const ProxyRouter = require('@extra/proxy-router')
chromium.use(
  ProxyRouter({
    proxies: { DEFAULT: 'http://user:pass@proxyhost:port' },
  })
)

// That's it, the default proxy will be used and proxy authentication handled automatically
chromium.launch({ headless: false }).then(async (browser) => {
  const page = await browser.newPage()
  await page.goto('https://canhazip.com', { waitUntil: 'domcontentloaded' })
  const ip = await page.evaluate('document.body.innerText')
  console.log('Outbound IP:', ip)
  await browser.close()
})

动态路由

灵活使用多个代理和路由连接

// playwright-extra is a drop-in replacement for playwright,
// it augments the installed playwright with plugin functionality
// Note: Instead of chromium you can use firefox and webkit as well.
const { chromium } = require('playwright-extra')

// Configure the proxy router plugin
const ProxyRouter = require('@extra/proxy-router')
const proxyRouter = ProxyRouter({
  // define the available proxies (replace this with your proxies)
  proxies: {
    // the default browser proxy, can be `null` as well for direct connections
    DEFAULT: 'http://user:pass@proxyhost:port',
    // optionally define more proxies you can use in `routeByHost`
    // you can use whatever names you'd like for them
    DATACENTER: 'http://user:pass@proxyhost2:port',
    RESIDENTIAL_US: 'http://user:pass@proxyhost3:port',
  },
  // optional function for flexible proxy routing
  // if this is not specified the `DEFAULT` proxy will be used for all connections
  routeByHost: async ({ host }) => {
    if (['pagead2.googlesyndication.com', 'fonts.gstatic.com'].includes(host)) {
      return 'ABORT' // block connection to certain hosts
    }
    if (host.includes('google')) {
      return 'DIRECT' // use a direct connection for all google domains
    }
    if (host.endsWith('.tile.openstreetmap.org')) {
      return 'DATACENTER' // route heavy images through datacenter proxy
    }
    if (host === 'canhazip.com') {
      return 'RESIDENTIAL_US' // special proxy for this domain
    }
    // everything else will use `DEFAULT` proxy
  },
})

// Add the plugin
chromium.use(proxyRouter)

// Launch a browser and run some IP checks
chromium.launch({ headless: true }).then(async (browser) => {
  const page = await browser.newPage()

  await page.goto('https://showmyip.com/', { waitUntil: 'domcontentloaded' })
  const ip1 = await page.evaluate("document.querySelector('#ipv4').innerText")
  console.log('Outbound IP #1:', ip1)
  // => 77.191.128.0 (the DEFAULT proxy)

  await page.goto('https://canhazip.com', { waitUntil: 'domcontentloaded' })
  const ip2 = await page.evaluate('document.body.innerText')
  console.log('Outbound IP #2:', ip2)
  // => 104.179.129.27 (the RESIDENTIAL_US proxy)

  console.log(proxyRouter.stats.connectionLog) // list of connections (host => proxy name)
  // { id: 0, proxy: 'DIRECT', host: 'accounts.google.com' },
  // { id: 1, proxy: 'DEFAULT', host: 'www.showmyip.com' },
  // { id: 2, proxy: 'ABORT', host: 'pagead2.googlesyndication.com' },
  // { id: 3, proxy: 'DEFAULT', host: 'unpkg.com' },
  // ...

  console.log(proxyRouter.stats.byProxy) // bytes used by proxy
  // {
  //   DATACENTER: 441734,
  //   DEFAULT: 125823,
  //   DIRECT: 100457,
  //   RESIDENTIAL_US: 4764,
  //   ABORT: 0
  // }

  console.log(proxyRouter.stats.byHost) // bytes used by host
  // {
  //   'a.tile.openstreetmap.org': 150685,
  //   'c.tile.openstreetmap.org': 147054,
  //   'b.tile.openstreetmap.org': 143995,
  //   'unpkg.com': 57621,
  //   'www.googletagmanager.com': 49572,
  //   'www.showmyip.com': 40408,
  // ...

  await browser.close()
})

进口

使用 Puppeteer 软件

该代码与上方剧作家例子基本相同. :-)

只需更改导入和包名 :

- const { chromium } = require('playwright-extra')
+ const puppeteer = require('puppeteer-extra')
// ...
- chromium.use(proxyRouter)
+ puppeteer.use(proxyRouter)
// ...
- chromium.launch()
+ puppeteer.launch()
// ...
字典和无害环境管理

该插件以Typescript和有型号的船来写.

剧作家 :

// You can use any browser: chromium, firefox, webkit
import { firefox } from 'playwright-extra'
import ProxyRouter from '@extra/proxy-router'
// ...
firefox.use(proxyRouter)

傀儡:

import puppeteer from 'puppeteer-extra'
import ProxyRouter from '@extra/proxy-router'
// ...
puppeteer.use(proxyRouter)

除错日志

如果您想看到调试输出 只运行您的脚本这样:

# macOS/Linux (Bash)
DEBUG=*proxy-router* node myscript.js

# Windows (Powershell)
$env:DEBUG='*proxy-router*';node myscript.js

如何运作

代理路由器会推出本地代理服务器并指示浏览器使用. 该本地代理服务器将依可选用户自定义的路由功能而与配置的上游代理服务器和中继连接相接,同时处理上游代理认证和其他几件事.

API 密码

选项

export interface ProxyRouterOpts {
  /**
   * A dictionary of proxies to be made available to the browser and router.
   *
   * An optional entry named `DEFAULT` will be used for all requests, unless overriden by `routeByHost`.
   * If the `DEFAULT` entry is omitted no proxy will be used by default.
   *
   * The value of an entry can be a string (format: `http://user:pass@proxyhost:port`) or `null` (direct connection).
   * Proxy authentication is handled automatically by the router.
   *
   * @example
   * proxies: {
   *   DEFAULT: "http://user:pass@proxyhost:port", // use this proxy by default
   *   RESIDENTIAL_US: "http://user:pass@proxyhost2:port" // use this for specific hosts with `routeByHost`
   * }
   */
  proxies?: {
    /**
     * The default proxy for the browser (format: `http://user:pass@proxyhost:port`),
     * if omitted or `null` no proxy will be used by default
     */
    DEFAULT?: string | null
    /**
     * Any other custom proxy names which can be used for routing later
     * (e.g. `'DATACENTER_US': 'http://user:pass@proxyhost:port'`)
     */
    [key: string]: string | null
  }

  /**
   * An optional function to allow proxy routing based on the target host of the request.
   *
   * A return value of nothing, `null` or `DEFAULT` will result in the DEFAULT proxy being used as configured.
   * A return value of `DIRECT` will result in no proxy being used.
   * A return value of `ABORT` will cancel/block this request.
   *
   * Any other string as return value is assumed to be a reference to the configured `proxies` dict.
   *
   * @note The browser will most often establish only a single proxy connection per host.
   *
   * @example
   * routeByHost: async ({ host }) => {
   *   if (host.includes('google')) { return "DIRECT" }
   *   return 'RESIDENTIAL_US'
   * }
   *
   */
  routeByHost?: RouteByHostFn
  /** Collect traffic and connection stats, default: true */
  collectStats?: boolean
  /** Don't print any proxy connection errors to stderr, default: false */
  muteProxyErrors?: boolean
  /** Suppress proxy errors for specific hosts */
  muteProxyErrorsForHost?: string[]
  /** Options for the local proxy-chain server  */
  proxyServerOpts?: ProxyServerOpts
  /**
   * Optionally exempt hosts from going through a proxy, even our internal routing proxy.
   *
   * Examples:
   * `.com` or `chromium.org` or `.domain.com`
   *
   * @see
   * https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md#proxy-bypass-rules
   * https://www-archive.mozilla.org/quality/networking/docs/aboutno_proxy_for.html
   */
  proxyBypassList?: string[]
}

替代品

代理. pace 文件 参考文献

  • 仅在头部模式下支持铬
    • 虽有名相FindProxyForURL) 只能通过主机进行路由
  • Firefox 支持 PAC 文件, 并且通过预览路径包含路径
  • 仅在浏览器启动时装入一次, 无法进行动态代理
  • 不处理认证

用于木偶机的各种“ 每页代理” 插件

  • 优点: 路由代理按页面而非主机
  • 他们依靠一个巨大的黑客:使用Node.js发送请求而不是浏览器
    • 将更改 TLS 指纹, 容易出错
  • CDP 请求截取仅为铬
  • 增加延迟和资源间接费用

许可证

版权: 2018-2023, 贝斯特恩德根据麻省理工学院的许可证释放.

版本与发布记录

@extra/proxy-router 共发布 5 个版本,首次发布于 2022/08/08;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.1.6latest2023/03/013 年前
3.1.52023/03/013 年前
3.1.42022/08/084 年前
3.1.32022/08/084 年前
3.1.22022/08/084 年前

关于 @extra/proxy-router 的常见问题

@extra/proxy-router 是什么?

用于剧作家和傀儡的插件,用于动态路由代理.

如何安装 @extra/proxy-router?

在项目目录运行 npm install @extra/proxy-router,或使用 pnpm add / yarn add / bun add。

@extra/proxy-router 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@extra/proxy-router 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@extra/proxy-router 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=14。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@extra/proxy-router 可以商用吗?

@extra/proxy-router 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@extra/proxy-router 的下载量有多少?

根据 npm 官方下载统计,@extra/proxy-router 在 2026/10/14 – 2026/11/12 这 30 天内被下载 155,102 次,日均约 5,170 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@extra/proxy-router 还在维护吗?

最新版本 3.1.6 发布于 2023/03/01(3 年前);至今共发布 5 个版本,其中过去 12 个月发布了 0 个;首次发布于 2022/08/08。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。