Playwright 怎么设置代理?Node.js 实测教程

在 Playwright 里给整个浏览器或每个上下文设置代理、填写账号密码、检查出口 IP,以及常见报错的处理方法。文中代码均已实际运行。

教程发布于 2026年10月25日约 4 分钟

本页目录

结论先说: 在 Playwright 里设置代理,就是传一个包含 server、username、password 的 proxy 对象:传给 chromium.launch(),整个浏览器共用一个代理;传给 browser.newContext(),每个上下文可以用不同的出口 IP。需要账号密码的代理要用 HTTP 或 HTTPS 协议,Playwright 不支持带账号密码的 SOCKS5。用 NanoIP 时,动态住宅和移动代理填 HTTPS 网关,静态 ISP 代理填 http://主机:端口。

启动时设置代理,页面 1、2、3 都使用 IP A;按上下文设置代理,上下文 1 使用 IP A,上下文 2 使用 IP B,上下文 3 使用 IP C
启动时设置的代理覆盖整个浏览器;按上下文设置,每个上下文有自己的出口 IP。

准备工作

需要安装 Node.js、Playwright 和浏览器:

bash
npm install playwright
npx playwright install chromium

下面的示例都是 ES 模块(.mjs 文件),使用顶层 await。Playwright 的 Python 版本用同样的 proxy 字段(server、username、password),设置方法可以直接对照。

给整个浏览器设置代理

把代理传给 launch(),浏览器打开的所有页面和上下文都会使用它。保存为 launch.mjs,用 node launch.mjs 运行:

js
import { chromium } from 'playwright';

const browser = await chromium.launch({
  proxy: {
    server: 'https://gateway.nanoip.net:1111',
    username: 'USERNAME',
    password: 'PASSWORD',
  },
});

const page = await browser.newPage();
await page.goto('https://ipinfo.io/json');
console.log(await page.textContent('body'));
await browser.close();

页面会以 JSON 输出出口 IP,以及它的 country、city 和 org。账号密码有单独的字段,所以密码里有 @、: 等字符也不需要转义。

给每个上下文设置不同的代理

浏览器上下文(context)是一个相互隔离的会话,Cookie、存储和缓存各自独立,相当于一个单独的浏览器环境。把 proxy 传给 newContext(),同一个浏览器里的每个上下文就能用不同的出口 IP,比每个代理启动一个浏览器更省资源。下面的 contexts.mjs 为每个代理开一个上下文:

js
import { chromium } from 'playwright';

const proxies = [
  { server: 'http://HOST_1:PORT_1', username: 'USERNAME_1', password: 'PASSWORD_1' },
  { server: 'http://HOST_2:PORT_2', username: 'USERNAME_2', password: 'PASSWORD_2' },
];

const browser = await chromium.launch();

for (const proxy of proxies) {
  const context = await browser.newContext({ proxy });
  const page = await context.newPage();
  await page.goto('https://ipinfo.io/ip');
  console.log(proxy.server, '→', (await page.textContent('body')).trim());
  await context.close();
}

await browser.close();

每一行输出是一个代理,以及网站通过它看到的 IP。某些地址不想走代理时,在代理对象里加 bypass,用逗号分隔,例如 bypass: 'localhost,.internal.example'。

Playwright 支持哪些代理

用 Playwright 1.61 在 Chromium 和 Firefox 中实测:带用户名密码的 http://主机:端口可用,登录由 Playwright 处理;1111 端口的 https 网关写法和 http:// 相同;带用户名密码的 socks5://主机:端口会报错,不支持 SOCKS5 认证
HTTP 和 HTTPS 代理可以带账号密码;带账号密码的 SOCKS5 不支持。

我们在 Chromium 和 Firefox 里都试了带账号密码的 SOCKS5 代理,Playwright 在启动时就报错:

text
browserType.launch: Browser does not support socks5 proxy authentication

所以只要代理需要登录,就用 HTTP 或 HTTPS。对网页来说没有损失,浏览器的网页流量走 HTTP 代理和走 SOCKS5 是一样的。SOCKS5 的优势在 UDP,浏览器自动化很少用到,区别见 SOCKS5和HTTP代理的区别。

正式运行前先检查代理

密码错了,Playwright 不会给出明确的报错。Chromium 会先不带账号连接代理,代理要求登录后,Playwright 再提交你填的账号;如果代理不接受,页面就一直等待。我们用错误密码测试时,page.goto() 一直等到超时才结束。所以在长时间任务之前,先用较短的超时检查一次,例如 check.mjs:

js
import { chromium } from 'playwright';

const proxy = { server: 'http://HOST:PORT', username: 'USERNAME', password: 'PASSWORD' };

const browser = await chromium.launch({ proxy });
const page = await browser.newPage();

try {
  const response = await page.goto('https://ipinfo.io/json', { timeout: 15_000 });
  const info = await response.json();
  console.log(`Exit IP ${info.ip} in ${info.city}, ${info.country} (${info.org})`);
} catch (error) {
  console.error('Proxy check failed:', error.message.split('\n')[0]);
} finally {
  await browser.close();
}

账号密码正确时,会输出一行出口 IP 和位置。密码错误时,我们得到的是:

text
Proxy check failed: page.goto: Timeout 15000ms exceeded.

第一个页面就超时,多半是账号密码的问题,而不是网站的问题。用 curl 测同一个代理就能区分:账号密码错误时,curl 会直接报 CONNECT tunnel failed, response 407。命令行检查方法见新手入门。

四种现象和处理方法:page.goto 一直等到超时,是用户名或密码错了;启动报错提示 socks5 代理认证,把协议改成 http://;页面显示的国家不对,检查路由设置或 bypass;每个上下文都是同一个 IP,给每个上下文单独的路由
Playwright 里常见的代理问题,基本是这四种。

在 Playwright 中使用 NanoIP 代理

动态住宅和移动代理

server 填 https://gateway.nanoip.net:1111,用户名和密码填控制台 Dynamic Routes 页面生成的路由信息。浏览器自动化建议选粘性会话:一个页面的 HTML、脚本和图片会通过多个连接加载,用轮换路由时,这些连接可能从不同的 IP 发出;粘性路由能让整个页面以及后续操作在你选择的时间内保持同一个 IP。要并行运行多个上下文,就为每个上下文生成一个粘性路由。轮换和粘性会话怎么选,见轮换会话和粘性会话的区别。

静态 ISP 代理

每个静态 ISP 代理都有自己的主机和端口。server 填 http://主机:端口,再填这个 IP 的用户名和密码;同一组账号也能用于 SOCKS5,但在 Playwright 里要用 HTTP。静态 ISP 的 IP 在整个套餐期内不变,适合每天登录同一个账号的上下文,比如多账号管理和店铺后台。

在多个地区采集公开页面,通常用动态住宅代理,每个上下文一个粘性路由,见数据采集。

常见问题

上下文创建后还能换代理吗?

不能。上下文会一直使用创建时的代理。要换代理,关闭它,再用新的代理创建一个上下文。

context.request 会走代理吗?

会。我们测试时,用 context.request 发出的接口请求经过了该上下文的代理。单独用 request.newContext() 创建的请求上下文,除非另外传入 proxy,否则不走代理。

Selenium 能用同样的方法吗?

不能直接套用。Selenium 驱动 Chrome 时,--proxy-server 参数只能填主机和端口,没有填写账号密码的地方,需要借助扩展或第三方工具来处理代理登录。需要带账号密码的代理时,Playwright 的设置更简单。

作者:NanoIP Team · Proxy infrastructure and customer support team

相关文章

对比

独享IP和共享IP有什么区别?代理怎么选

独享代理IP在套餐期内只有你在用,共享IP同时有多个用户。本文用图讲清共享会带来哪些影响、各自适合什么场景,以及购买前要问服务商的五个问题。

约 5 分钟

配置遇到问题?

我们的技术支持团队可以和你一起检查代理配置。