可在Telegram上免费试用:法国 、英国 或新加坡 加入Telegram
浏览器自动化

结合 Selenium 和 Playwright 的移动端代理

通过经过身份验证的移动代理驱动真实浏览器——Playwright的“按上下文”代理、那个让人白白浪费一个下午的Chrome凭证陷阱,以及如何正确解读407错误代码而非靠猜测。

PXM2 Proxies August 20, 2026 阅读时间 8 分钟
原生 Playwright 代理授权
根据上下文 独立的出口IP地址
无限 带宽与轮换
5+ 可用国家数
  • Playwright 中的第一类身份验证 — 用户名和密码是参数,而不是权宜之计。
  • IP白名单 — 当Selenium从固定主机运行时,这是最稳定的选项。
  • 按上下文划分的退出 IP 地址 — 在一个浏览器进程中运行多个身份,且不会相互影响。
  • 真实运营商IP地址 — 由实际移动网络支持的移动指纹。
4G/5G移动代理 IP 或用户认证
协议支持HTTP(S), SOCKS5
身份验证IP白名单或用户名/密码
带宽无限
硬件专属4G/5G调制解调器
匹配的指纹

由真实的移动端退出IP支持的移动端视口和区域设置。

每个上下文一个 IP 地址

在一个进程中运行并行身份,且这些身份不共享同一地址。

仅在没有浏览器就无法获取数据时,才使用真正的浏览器。如果标记内容包含在初始响应中,HTTP 客户端的开销要小一个数量级——Python 指南中已介绍了这种情况。下文将介绍必须运行 JavaScript 以及代理必须能够与浏览器正常交互的情况。

工具 原生代理身份验证 按上下文设置代理 结论
Playwright 是的——用户名和密码是参数 代理服务器需要凭据时的默认选项
Selenium 不——URL 中的凭据将被忽略 不——每个驱动程序实例仅有一个代理 在启用IP白名单的情况下可行;否则操作起来比较麻烦
Puppeteer 部分实现——通过 page.authenticate() 按浏览器计算,而非按上下文计算 对于已经使用该功能的 Node 堆栈来说没问题

剧作家:启动时的代理,按上下文确定的代理

Playwright 将代理凭据视为一等参数,并自行处理身份验证挑战。无需加载任何扩展,也无需注入任何头部:

Python · Playwright
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        "server": "http://proxy.pxm2.io:8000",
        "username": "user",
        "password": "pass",
    })
    ctx = browser.new_context(
        locale="en-GB",
        timezone_id="Europe/London",
        viewport={"width": 390, "height": 844},
        is_mobile=True,
    )
    page = ctx.new_page()
    page.goto("https://example.com/listings", wait_until="domcontentloaded")
    page.wait_for_selector(".result-card")
    html = page.content()
    browser.close()
示例端点和凭据

当在一个进程中运行多个身份时,请按上下文而非按浏览器设置代理——new_context 接受相同的代理字典,因此每个上下文都会拥有独立的退出 IP、独立的 Cookie 存储和独立的存储空间,彼此之间不会产生交叉污染。 同一上下文中的标签页共享网络堆栈,因此若需独立身份,应创建独立的上下文,而非单独的标签页。

请注意,该代码片段中的上下文选项还承担着另一项功能。设置了 is_mobile 的移动视口、区域设置和时区并非可有可无的装饰——它们构成了一项断言中属于浏览器端的部分,而网络端的部分则是移动设备的出口 IP 地址。如果其中一项正确而另一项错误,其后果比两者都不正确更严重,因为这种不匹配本身就是一种信号。

Selenium 与“经过身份验证的代理”陷阱

Selenium 是一种较早的选项,在决定采用它之前,有几点需要注意:Chrome 的 --proxy-server 开关不接受用户名和密码。如果将它们传递到 URL 中,系统会默默忽略,随后浏览器会卡在原生认证对话框上,而 WebDriver 无法关闭该对话框。 其表现为:脚本在首次导航时会卡住,且完全不会显示任何错误信息。

Python · Selenium
from selenium import webdriver

opts = webdriver.ChromeOptions()
opts.add_argument("--proxy-server=http://proxy.pxm2.io:8000")

# NOTE: user:pass in the URL above is IGNORED by Chrome.
# Pick one of:
#   1. IP authorisation  - allow-list your server IP, use no credentials
#   2. selenium-wire-lw  - injects the Proxy-Authorization header
#   3. a small MV3 extension that answers onAuthRequired

driver = webdriver.Chrome(options=opts)
driver.get("https://example.com/listings")
示例端点和凭据

当您的爬虫从固定主机运行时,IP授权是这三种方式中最稳健的。无需传输任何凭据,无需注入任何内容,也不需要维持任何额外的依赖项。

如果您要使用 Selenium Wire,请确认您正在安装的是哪个包。原始的 wkeeling/selenium-wire 仓库已于 2024 年 1 月归档,且不再维护;已固定的配置仍可正常工作,但随着依赖项的更新,新搭建的环境往往会出现问题。 正在维护的 selenium-wire-lw 分支保留了相同的 seleniumwire 导入,是新项目应采用的版本。

如果你主要是出于习惯才使用 Selenium,而且需要经过身份验证的代理,那么 Playwright 可以彻底解决这个问题——而且这种解决方式比上述三种变通方法都要更持久。

调试 407 错误和代理认证失败

“407 需要代理身份验证”意味着代理服务器收到了您的请求,但因无法验证您的身份而拒绝了该请求。在浏览器自动化操作中,这几乎总是意味着凭据从未送达,而非凭据本身有误。请按以下顺序排查,通常前两个步骤就能找到原因:

  1. 先让未经过身份验证的shape正常工作

    将您的 IP 地址临时加入白名单,或者使用无需凭据的端点,并确认浏览器能否访问目标地址。这样可以区分代理问题和浏览器配置问题,而这两者的调试方法截然不同。

  2. 先运行“有头”模式,再运行“无头”模式simplified-chinese (Mainland)

    在无头模式下,原生身份验证对话框不可见,而在真实窗口中则清晰可见。如果带头模式下显示了凭据提示框,那就说明你找到了它——这表明 Chrome 正在告诉你,该开关从未携带过你的用户名和密码。

  3. 通过同一浏览器验证出口IP地址

    访问一个 IP-echo 服务并读取该地址。如果该地址是您自己的,则说明代理设置被完全忽略了——这是端点字符串格式错误的常见结果,因为大多数协议栈会采取“开放处理”策略,而非抛出异常。

  4. 只有到那时,才添加身份验证

    既然已有通往目标的已知有效路径,那么认证失败现在只有一个可能的原因,而不是四个。

在断定是凭据有问题之前,还有一点值得检查:你所运行的主机是否在服务商的白名单上。服务器迁移后,或者容器启动后获得了新地址,都会导致与密码输入错误完全相同的407错误。

无头泄漏:使浏览器与IP地址匹配

一个干净的移动IP地址,即使搭配默认的无界面浏览器,仍然会显露出是机器人。代理仅解决了由多个层级构成的评分体系中的其中一层,而以下这些层级是它无法触及的:

  • 自动化标记 — navigator.webdriver、缺失的插件和编解码器信息,以及一个显示为 SwiftShader 的 WebGL 渲染器,这些都表明这是一个自动化浏览器。请在虚拟显示器下运行 headful,或使用隐身插件,并通过指纹检测页面进行验证,而不是凭空猜测。
  • 地理一致性 — 来自英国的IP地址与报告为“America/New_York”且语言为“en-US”的浏览器之间存在不匹配,这属于常规检查项。请在上下文中设置locale和timezone_id,使其与您所在的离开国家/地区相符。
  • 设备一致性 — 如果你设置了手机视口和 is_mobile 属性,则退出 IP 应为手机 IP,且 User-Agent 应与这两者均一致。不完整的手机身份信息比完全没有更引人注目。
  • 行为 — 系统会测量间隔是否完全均匀、鼠标是否静止以及表单填写是否瞬间完成。代理无法掩盖访问模式;只有改变访问模式才能做到这一点。

在添加另一层规避措施之前,请打开“网络”选项卡。你正在让整个浏览器渲染的页面,其数据通常是从一个内部端点获取的,该端点返回的是纯净的 JSON——你可以直接使用 HTTP 客户端调用该端点,无需浏览器,也完全不会留下任何指纹痕迹。

获取专用浏览器代理

PXM2实时节点——选择您希望目标用户看到请求来自的国家/地区,即可获得一个专属的4G/5G IP地址,该地址提供无限带宽和轮询功能:

🇫🇷

法国

3 名操作员 20-150 Mbps
从……开始
$4.34 1小时时长
4G 5G
可用运算符:
SFR Bouygues Orange
🇮🇳

印度

3 名操作员 20-30 Mbps
从……开始
$2.74 1小时时长
4G
可用运算符:
Airtel Jio Vodafone Idea (Vi)
🇸🇬

新加坡

2 名操作员 30-70 Mbps
从……开始
$2.99 1小时时长
4G
可用运算符:
Vivifi Singtel
查看所有地点 →

常见问题解答

如何在 Selenium 中使用需要身份验证的代理?

不能通过命令行实现——Chrome 的 --proxy-server 参数会忽略 URL 中的用户名和密码,随后浏览器会因出现一个 WebDriver 无法关闭的原生对话框而卡住。 有三种可行的解决方案:将您主机的 IP 地址加入白名单以避免输入凭据;使用一个维护良好的 Selenium Wire 分支来注入 Proxy-Authorization 头;或者加载一个小型扩展程序来响应 onAuthRequired 事件。

Playwright 是否支持代理身份验证?

是的,原生支持。launch 和 new_context 都接受一个包含 server、username 和 password 键的代理字典,而 Playwright 会自行处理身份验证。当您的代理需要凭据时,这是选择 Playwright 而非 Selenium 的最明确理由。

“407 需要代理身份验证”是什么意思?

代理服务器接收到了您的请求,但因无法验证您的身份而将其拒绝。在浏览器自动化操作中,这几乎总是意味着凭据从未到达代理服务器,而非凭据本身有误——可能是某个开关被无声地关闭了,某个扩展程序未加载,或者该主机未列入允许列表。

selenium-wire 项目还在维护吗?

原始的 wkeeling/selenium-wire 代码库已于 2024 年 1 月归档,此后便不再维护。已锁定的安装仍可正常运行,但随着依赖项的更新,新环境往往会出现问题。 对于新项目,请使用经过维护的 selenium-wire-lw 分支(该分支保留了相同的 seleniumwire 导入),或者通过将您的 IP 加入白名单或迁移至 Playwright 来完全避免此问题。

我能否为每个浏览器标签页或上下文使用不同的代理?

就上下文而言,是的——Playwright 的 new_context 会使用其自身的代理,因此每个上下文都会获得独立的出口 IP、Cookie 存储和存储空间,彼此之间不会发生数据泄漏。就同一上下文内的各个标签页而言,则不是:同一上下文中的标签页共享网络堆栈。如果您需要独立的身份,请使用不同的上下文。

浏览器自动化是一条成本较高的途径。本系列的其他文章将介绍成本较低的方法,以及如何在最初阶段选择代理层。

网页抓取指南

核心移动代理指南

通过真实运营商的IP地址驱动真实浏览器

配备IP白名单或用户凭证功能的专用4G/5G调制解调器——每个浏览器上下文均配有独立的出口IP地址,且无论页面加载多少次,均享有无限带宽。

获取浏览器代理