Playwright 是最强大的浏览器自动化、无头测试和数据解析工具之一。但如果没有正确配置的代理,您的脚本很快就会因 IP 被封:网站已经学会识别自动化请求并阻止它们。在本指南中,我们将讨论在 Playwright 中连接代理的所有方法 - 从基本配置到 IP 轮换和绕过 Cloudflare。
为什么在 Playwright 中使用代理,什么时候必须使用代理
Playwright 在后台运行真实的浏览器(Chromium、Firefox 或 WebKit)——这就是无头模式。从网站的角度来看,您看起来像普通用户,但仅限于某个时刻。一旦从一个 IP 发出每小时数百个请求,保护算法会立即做出反应:CAPTCHA、临时封锁、完全封禁。
以下是必须使用代理的具体场景:
- 解析市场 — Wildberries、Ozon、Avito、Yandex.Market 在从一个 IP 发出 50-100 个请求后会阻止脚本。
- 监控竞争对手价格 — 如果每 15 分钟进行一次检查,未更换 IP 您将在几个小时内被封禁。
- 地理位置测试 — 需要检查网站在德国、美国或哈萨克斯坦用户的显示效果。
- 填写表单和注册帐户 — 平台将帐户绑定到 IP 并阻止批量注册。
- SEO 监控 — 从 Google 和 Yandex 收集排名需要不断更换 IP,否则搜索引擎会显示 CAPTCHA。
- A/B 功能测试 — 某些功能仅对特定国家或地区的用户可用。
重要的是要理解:Playwright 本身并不能使您匿名。没有代理,所有请求都来自您的真实 IP 地址。添加代理是任何自动化脚本稳定运行的第一步和最重要的一步。
💡 重要提示
Playwright 支持在整个浏览器、单个上下文(BrowserContext)甚至单个页面上使用代理。这提供了灵活性:不同的页面可以同时通过不同的 IP 工作。
选择哪种类型的代理用于无头自动化
并非所有代理都适合 Playwright。选择取决于任务:您正在解析什么,网站的保护有多激进,以及您计划发送多少请求。
| 代理类型 | 信任级别 | 速度 | 适合于 |
|---|---|---|---|
| 数据中心 | 低 | 非常高 | 没有严格保护的解析,测试 |
| 住宅 | 高 | 中等 | 带有 Cloudflare 的网站,市场,社交网络 |
| 移动 | 最高 | 中等 | Facebook、TikTok、Instagram、严格的反机器人 |
| SOCKS5 | 取决于来源 | 高 | 通用协议,Playwright 支持 |
对于大多数解析任务,最佳选择是带有轮换的住宅代理。它们具有真实的家庭用户 IP,因此网站不会将其识别为数据中心并自动阻止。对于具有激进保护的网站(Cloudflare Bot Management、Akamai),最好使用移动代理——它们的 IP 属于移动运营商,从而引起最大的信任。
Playwright 支持 http、https 和 socks5 协议。重要的是:某些版本的 SOCKS5 不支持通过用户名:密码直接进行身份验证——有关此的更多信息请参见错误部分。
在 Playwright 中的代理基本设置(JavaScript 和 Python)
Playwright 允许通过参数 proxy 在启动浏览器时设置代理。这是最简单的方法——所有浏览器请求都将通过指定的代理服务器进行。
JavaScript / Node.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
proxy: {
server: 'http://proxy.example.com:8080'
}
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
const content = await page.textContent('body');
console.log(content); // 将显示代理服务器的 IP
await browser.close();
})();
Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://proxy.example.com:8080"
}
)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.text_content("body")) # 将显示代理的 IP
browser.close()
对于 SOCKS5,只需在服务器地址中更改方案:
# Python — SOCKS5 代理
browser = p.chromium.launch(
proxy={
"server": "socks5://proxy.example.com:1080"
}
)
要快速检查代理是否工作,请打开 https://httpbin.org/ip 或 https://api.ipify.org — 响应中应显示代理服务器的 IP,而不是您的真实 IP。
使用用户名和密码进行身份验证的代理
大多数商业代理提供商使用用户名和密码进行身份验证——这是标准做法。Playwright 通过代理对象中的 username 和 password 字段支持它。
JavaScript
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyprovider.com:7777',
username: 'your_login',
password: 'your_password'
}
});
Python
browser = p.chromium.launch(
proxy={
"server": "http://gate.proxyprovider.com:7777",
"username": "your_login",
"password": "your_password"
}
)
还可以直接在代理服务器的 URL 中传递用户名和密码——如果您动态生成字符串,这很方便:
# 在 URL 中进行身份验证(Python)
proxy_url = f"http://{login}:{password}@gate.proxyprovider.com:7777"
browser = p.chromium.launch(
proxy={"server": proxy_url}
)
⚠️ 注意
请勿将代理的用户名和密码直接存储在代码中!使用环境变量(os.environ 在 Python 中或 process.env 在 Node.js 中)或使用 dotenv 库的 .env 文件。
通过 .env 安全存储(Python)
import os
from dotenv import load_dotenv
from playwright.sync_api import sync_playwright
load_dotenv()
PROXY_SERVER = os.getenv("PROXY_SERVER")
PROXY_LOGIN = os.getenv("PROXY_LOGIN")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": PROXY_SERVER,
"username": PROXY_LOGIN,
"password": PROXY_PASSWORD
}
)
# ...
代理轮换:每个请求更换 IP
单个代理无法在大量请求时避免封禁。对于严肃的解析,需要 IP 轮换——在特定间隔内或每个新请求自动更换代理服务器。
Playwright 中有两种轮换方法:
方法 1:轮换代理端点
大多数住宅代理提供商提供一个统一的网关地址,每次连接时自动更换 IP。您无需编写轮换逻辑——它在提供商的一侧内置。
# 一个端点 — 每次浏览器连接时更换 IP
browser = p.chromium.launch(
proxy={
"server": "http://rotating.proxyprovider.com:8888",
"username": "your_login",
"password": "your_password"
}
)
方法 2:通过代理列表手动轮换
如果您有一个静态代理列表,可以通过手动创建新的浏览器或上下文来实现轮换:
import random
from playwright.sync_api import sync_playwright
PROXY_LIST = [
{"server": "http://proxy1.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy2.example.com:8080", "username": "user", "password": "pass"},
{"server": "http://proxy3.example.com:8080", "username": "user", "password": "pass"},
]
URLS_TO_SCRAPE = [
"https://example.com/page1",
"https://example.com/page2",
"https://example.com/page3",
]
with sync_playwright() as p:
for url in URLS_TO_SCRAPE:
proxy = random.choice(PROXY_LIST) # 随机代理
browser = p.chromium.launch(proxy=proxy)
page = browser.new_page()
page.goto(url)
# ... 解析数据 ...
browser.close() # 关闭浏览器,更换 IP
方法 3:通过 BrowserContext 轮换(无需重启浏览器)
with sync_playwright() as p:
browser = p.chromium.launch() # 无代理的浏览器
for i, url in enumerate(URLS_TO_SCRAPE):
proxy = PROXY_LIST[i % len(PROXY_LIST)] # 循环使用
# 新的上下文与新代理 — 比重启浏览器更快
context = browser.new_context(proxy=proxy)
page = context.new_page()
page.goto(url)
# ... 解析 ...
context.close() # 关闭上下文,不关闭浏览器
browser.close()
第三种方法是大规模解析的最高效方式。重启浏览器需要 2-4 秒,而创建新上下文则少于 100 毫秒。
上下文和页面级别的代理
Playwright 支持灵活的架构:一个浏览器可以有多个隔离的上下文,每个上下文都有自己的代理。这使得在一个进程中并行使用多个 IP 成为可能。
多个上下文与不同代理(并行解析)
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
// 上下文 1 — 来自德国的代理
const context_de = await browser.newContext({
proxy: {
server: 'http://de-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
// 上下文 2 — 来自美国的代理
const context_us = await browser.newContext({
proxy: {
server: 'http://us-proxy.example.com:8080',
username: 'user',
password: 'pass'
}
});
const page_de = await context_de.newPage();
const page_us = await context_us.newPage();
// 并行启动
await Promise.all([
page_de.goto('https://example.com'),
page_us.goto('https://example.com')
]);
// 两个页面看到不同的 IP
console.log('DE IP:', await page_de.textContent('body'));
console.log('US IP:', await page_us.textContent('body'));
await browser.close();
})();
这种方法非常适合地理位置测试:您可以同时检查网站在不同国家用户的显示效果,而无需启动多个浏览器实例。
💡 性能建议
为了最大程度的并行性,请在 Python 中使用 asyncio 或在 Node.js 中使用 Promise.all。一个浏览器可以保持 10-20 个并行上下文,而不会对内存造成显著负担。
绕过反机器人保护:Cloudflare、Akamai、DataDome
代理只是解决方案的一部分。现代反机器人系统同时分析数十个信号:浏览器指纹、鼠标行为、表单填写速度、HTTP 头等。即使使用良好的代理,如果不考虑这些因素,您也可能会被封禁。
1. 隐藏无头模式
Playwright 在无头模式下具有易于识别的特征:特定的 navigator.webdriver 值、缺少插件、非标准屏幕尺寸。使用 playwright-stealth 库进行隐藏:
# Python: 安装
# pip install playwright-stealth
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync
with sync_playwright() as p:
browser = p.chromium.launch(
proxy={
"server": "http://residential.proxyprovider.com:8888",
"username": "user",
"password": "pass"
}
)
page = browser.new_page()
stealth_sync(page) # 应用隐藏
page.goto("https://bot.sannysoft.com") # 机器人检测测试
browser.close()
2. 真实的 User-Agent 和视口
context = browser.new_context(
proxy={
"server": "http://proxy.example.com:8080",
"username": "user",
"password": "pass"
},
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
viewport={"width": 1920, "height": 1080},
locale="ru-RU",
timezone_id="Europe/Moscow" # 应与代理的地理位置一致!
)
3. 模拟人类行为
import time
import random
# 动作之间的随机延迟
def human_delay(min_ms=500, max_ms=2000):
time.sleep(random.randint(min_ms, max_ms) / 1000)
page.goto("https://example.com")
human_delay()
# 平滑滚动而不是瞬间滚动
page.evaluate("window.scrollBy({top: 500, behavior: 'smooth'})")
human_delay(300, 800)
# 点击前移动鼠标
page.mouse.move(100, 200)
human_delay(100, 300)
page.mouse.move(300, 400)
human_delay(100, 200)
page.click("button#submit")
4. 时区与代理的地理位置一致
这常常被忽视,但反机器人系统会检查一致性:如果您的代理来自莫斯科,而浏览器显示的时区是 UTC-8(洛杉矶)——这是一个红旗。始终根据所使用的代理设置 timezone_id。
常见错误及其解决方法
在 Playwright 中使用代理时,开发人员经常遇到相同的问题。我们将逐一讨论每个问题及其具体解决方案。
错误 1:ERR_PROXY_CONNECTION_FAILED
原因:代理地址或端口不正确,代理不可用,凭据不正确。
解决方案:在启动 Playwright 之前,通过 curl 检查代理的可用性:
# 通过 curl 检查代理
curl -x http://user:[email protected]:8080 https://api.ipify.org
错误 2:SOCKS5 不接受身份验证
原因:Playwright(Chromium)对通过 username/password 进行身份验证的 SOCKS5 支持有限。
解决方案:使用带身份验证的 HTTP 代理或通过 ssh -D 设置本地 SOCKS5 隧道,无需密码。
错误 3:代理工作,但网站仍然封锁
原因:使用了数据中心代理,这些代理在黑名单中;未隐藏无头模式;请求频率过高。
解决方案:切换到住宅或移动代理,添加 playwright-stealth,增加请求之间的延迟。
错误 4:真实 IP 泄漏(DNS 泄漏)
原因:DNS 请求可能绕过代理。
解决方案:在使用 HTTP 代理时,Playwright 默认通过代理发送 DNS 请求。但要检查,请在无头浏览器中使用 https://dnsleaktest.com。
错误 5:代理工作缓慢
原因:住宅代理比数据中心代理慢;与代理服务器的距离较远。
解决方案:选择地理位置较近的代理。对于没有严格匿名性要求的任务,使用数据中心代理——它们速度更快得多。
| 错误 | 快速解决方案 |
|---|---|
| ERR_PROXY_CONNECTION_FAILED | 检查 curl、登录/密码、端口可用性 |
| 407 代理身份验证所需 | 在代理配置中添加用户名和密码 |
| 网站显示 CAPTCHA | 将代理类型更改为住宅代理,添加 stealth |
| 轮换时 IP 不变 | 在请求之间关闭上下文/浏览器 |
| 连接超时 | 在 goto() 中增加超时,选择更近的代理 |
结论和建议
在 Playwright 中设置代理不是一次性任务,而是您自动化工具架构的一部分。正确选择代理类型、合理的 IP 轮换和隐藏无头模式共同确保在具有激进反机器人保护的网站上稳定运行。
总结一下针对具体任务选择代理类型的要点:
- 解析开放数据没有严格保护 — 适合快速的数据中心代理。
- 市场(Wildberries、Ozon)、新闻聚合器 — 需要带有轮换的住宅代理。
- 社交网络(Instagram、Facebook、TikTok)和带有 Cloudflare 的网站 — 仅限移动或住宅代理。
- 地理位置测试 — 需要在目标国家的任何类型代理,关键是时区一致。
- 高频率的大规模解析 — 轮换的住宅代理与网关端点。
如果您正在构建基于 Playwright 的解析或自动化测试系统,并且需要稳定的无封锁运行,建议考虑 住宅代理 — 它们提供了网站的高信任级别,并通过单一端点支持 IP 轮换,这使得与 Playwright 的集成简化到几行代码。