Playwright 代理配置完整指南:Context 隔离、认证与会话策略

发布时间
阅读时长约 5 分钟

Key Takeaways

面向中文开发者的 Playwright 代理实施指南,覆盖 TypeScript 代码、Context 级代理、地域一致性、错误分类和生产检查清单。

🎭
Playwright 中的代理不是页面打开后再切换的临时参数。应把 BrowserContext、代理会话、Cookie、语言与时区 视为同一个浏览身份边界。

本文使用 TypeScript 展示浏览器级和 Context 级代理配置,并给出出口验证、407、隧道失败、错地区和超时的排查方法。

安装

bash
mkdir playwright-proxy-zh
cd playwright-proxy-zh
npm init -y
npm install playwright typescript tsx
npx playwright install chromium

环境变量:

bash
PROXY_SERVER=http://proxy.example.com:8001
PROXY_USERNAME=customer-123-country-US
PROXY_PASSWORD=replace-me
IP_CHECK_URL=https://iprobe.io/json

浏览器级代理

typescript
import { chromium } from 'playwright';

const browser = await chromium.launch({
  headless: true,
  proxy: {
    server: process.env.PROXY_SERVER!,
    username: process.env.PROXY_USERNAME,
    password: process.env.PROXY_PASSWORD,
  },
});

try {
  const context = await browser.newContext();
  const page = await context.newPage();

  const response = await page.goto(
    process.env.IP_CHECK_URL || 'https://iprobe.io/json',
    { waitUntil: 'domcontentloaded', timeout: 45_000 },
  );

  if (!response) throw new Error('没有收到导航响应');
  console.log(response.status());
  console.log(await page.locator('body').innerText());

  await context.close();
} finally {
  await browser.close();
}

Playwright 官方 BrowserType 文档说明代理对象支持 HTTP 和 SOCKS 服务器,并可为 HTTP 代理提供用户名和密码。参见 Playwright BrowserType

Context 级代理

当一个浏览器进程需要处理多个独立市场或账号时,可以为每个 Context 配置代理:

typescript
const browser = await chromium.launch();

const usContext = await browser.newContext({
  proxy: {
    server: process.env.PROXY_SERVER!,
    username: 'customer-123-country-US',
    password: process.env.PROXY_PASSWORD,
  },
  locale: 'en-US',
  timezoneId: 'America/New_York',
});

const deContext = await browser.newContext({
  proxy: {
    server: process.env.PROXY_SERVER!,
    username: 'customer-123-country-DE',
    password: process.env.PROXY_PASSWORD,
  },
  locale: 'de-DE',
  timezoneId: 'Europe/Berlin',
});

每个 Context 隔离 Cookie、本地存储和页面状态。不同代理身份不要混用同一个 Context。

先验证代理,再访问真实目标

建议按顺序执行:

  1. 使用 curl 验证同一组凭证。
  2. 使用 Playwright 访问中立 IP 检测页。
  3. 确认出口 IP 与请求地域。
  4. 使用最小脚本访问获得授权的真实目标。
  5. 验证业务内容,而不是只看 HTTP 200。
bash
curl --proxy 'http://proxy.example.com:8001' \
  --proxy-user 'customer-123-country-US:replace-me' \
  --connect-timeout 15 --max-time 30 \
  'https://iprobe.io/json'

轮换与粘性会话

代理是否轮换通常由代理服务的凭证或会话参数决定,而不是 Playwright 自动完成。

轮换适合: 独立商品页、公开列表页、一次性快照。

粘性适合: 登录、多步骤表单、购物车、分页状态、浏览器 Agent。

粘性任务应在同一个 Context 中完成,并在逻辑任务结束后关闭 Context。

地域一致性

代理 IP 只是地域的一部分。还需要检查:

  • 浏览器语言
  • 时区
  • URL 市场参数
  • Cookie
  • 账号地区
  • 配送地址或邮编
typescript
const context = await browser.newContext({
  proxy: getProxy(),
  locale: 'en-GB',
  timezoneId: 'Europe/London',
});

最终应验证页面实际返回的币种、语言、库存或搜索市场。

不要默认等待 networkidle

现代页面可能持续发送分析、轮询或流式请求。更可靠的方式是:

typescript
await page.goto(targetUrl, {
  waitUntil: 'domcontentloaded',
  timeout: 45_000,
});

await page.locator('[data-testid="price"]').first().waitFor({
  state: 'visible',
  timeout: 15_000,
});

等待代表业务数据已出现的元素,而不是等待网络完全安静。

记录网络失败与 HTTP 错误

typescript
page.on('requestfailed', request => {
  console.error({
    type: 'request_failed',
    url: request.url(),
    error: request.failure()?.errorText,
  });
});

page.on('response', response => {
  if (response.status() >= 400) {
    console.warn({
      type: 'http_error',
      status: response.status(),
      url: response.url(),
    });
  }
});

requestfailed 表示浏览器未获得正常 HTTP 响应;403、407、429 等通常需要通过 response 状态单独识别。

常见错误

现象优先检查
407用户名、密码、端口、凭证格式
ERR_PROXY_CONNECTION_FAILED代理主机、DNS、端口、防火墙
ERR_TUNNEL_CONNECTION_FAILED协议与端口、认证、CONNECT 路径
超时代理连接、目标响应、等待条件
IP 正确但地区内容错误Cookie、语言、时区、账号和 URL
登录后流程失败是否中途轮换、Context 是否重建

重试必须改变条件

  • 407:停止重试并修复凭证
  • 连接瞬时失败:有限更换路由
  • 429:降低频率并退避
  • 明确拒绝:停止并复核授权
  • 解析失败:保存页面证据并更新解析器

不要使用无限轮换掩盖配置或政策问题。

Trace 排错

typescript
await context.tracing.start({
  screenshots: true,
  snapshots: true,
  sources: true,
});

try {
  await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
} finally {
  await context.tracing.stop({ path: 'trace.zip' });
}

查看:

bash
npx playwright show-trace trace.zip

Trace 可能包含敏感 URL、页面和状态,分享前必须人工检查。

生产检查清单

  1. 固定 Playwright 和浏览器版本。
  2. 凭证存入密钥管理系统。
  3. curl 与 Playwright 使用完全相同的代理参数。
  4. 每个身份使用独立 Context。
  5. 出口地域与页面业务地域同时验证。
  6. 轮换与粘性按任务边界选择。
  7. 重试次数、总时间和流量有限制。
  8. 日志中不出现完整密码或会话参数。
  9. 使用 finally 关闭 Context 和浏览器。
  10. 目标访问已获得授权。

相关内容

AV
技术团队背书同行架构师审查 & 实测校验

Alex Vance

核心基础设施架构团队

本文由 BytesFlows 工程团队审查。代码示例适用于合规的公开网页数据采集、QA 自动化、SEO 监测与市场研究工作流。实际基准表现可能因目标站点防爬策略、地理位置、客户端运行环境及请求频率而异。