Selenium代理认证:4种实际有效的设置

Chrome弹出Selenium无法触及的认证对话框,URL中嵌入凭证的技巧悄然失效。以下是四种在Selenium中实际认证代理的方法——按对系统影响的轻重排序。

Selenium代理认证是一个伪装成单行代码的陷阱。--proxy-server Chrome标志愉快地接受代理地址——并悄然忽略任何嵌入的用户名和密码。随后Chrome弹出一个WebDriver无法看到的本地认证对话框,脚本挂起,而你找到的Stack Overflow上得票最高的答案(113+票)用一个现代Chrome不再加载的Manifest V2扩展解决了这个问题。本指南涵盖了今天在Selenium中认证代理的四种设置——IP白名单、Manifest V3扩展、selenium-wire,以及何时将整个浏览器问题交给API。

为什么基本的Selenium代理认证会失败

三个事实解释了每一次失败的尝试。首先,Chromium从--proxy-server=http://user:pass@host:port中剥离凭证——标志格式根本不支持凭证。其次,代理的407 Proxy Authentication Required挑战以本地对话框的形式出现,位于DOM之外,send_keys无法触及。第三,旧的DesiredCapabilities路径(socksUsername / socksPassword)仅适用于SOCKS代理,从未对HTTP代理有效——看似正确的配置却无效。因此,真正的选项完全避免对话框。

方法1:IP白名单——零代码,零对话框

如果你的抓取器运行在具有稳定公共IP的机器上,完全跳过凭证:在你的代理提供商的仪表板中注册该IP,网关通过源地址认证你。每个QuantumProxies计划都支持IP白名单和user:pass。Selenium端变成了简单的标志——一直以来在没有认证的情况下都能正常工作:

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--proxy-server=http://gate.quantumproxies.io:PORT")
options.add_argument("--headless=new")

driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)  # proxy exit IP
driver.quit()

在信任运行之前始终验证出口:加载一个IP回显端点并确认地址属于代理,因为配置错误的标志会悄然失败,Chrome直接连接。白名单的限制是拓扑性的:它认证的是机器,而不是脚本。临时云运行器、NAT后的容器和IP变化的CI机器需要下面的方法之一。

方法2:Manifest V3 Chrome扩展

经典修复生成一个小型Chrome扩展,通过chrome.webRequest.onAuthRequired设置代理并回答认证挑战。著名的2019年代码片段使用Manifest V2,Chrome现在已停用——现代版本需要manifest_version: 3、一个服务工作者和webRequestAuthProvider权限。这在运行时构建并加载一个:

import json, os, tempfile
from selenium import webdriver

HOST, PORT = "gate.quantumproxies.io", "PORT"
USER, PASS = "USER", "PASS"

manifest = {
    "name": "Proxy Auth", "version": "1.0", "manifest_version": 3,
    "permissions": ["proxy", "webRequest", "webRequestAuthProvider"],
    "host_permissions": ["<all_urls>"],
    "background": {"service_worker": "worker.js"},
}

worker = """
chrome.proxy.settings.set({
  value: { mode: "fixed_servers", rules: {
    singleProxy: { scheme: "http", host: "%s", port: parseInt("%s") },
    bypassList: ["localhost"] } },
  scope: "regular"
}, function() {});
chrome.webRequest.onAuthRequired.addListener(
  function(details) {
    return { authCredentials: { username: "%s", password: "%s" } };
  },
  { urls: ["<all_urls>"] },
  ["blocking"]
);
""" % (HOST, PORT, USER, PASS)

ext_dir = tempfile.mkdtemp()
with open(os.path.join(ext_dir, "manifest.json"), "w") as f:
    json.dump(manifest, f)
with open(os.path.join(ext_dir, "worker.js"), "w") as f:
    f.write(worker)

options = webdriver.ChromeOptions()
options.add_argument("--load-extension=" + ext_dir)
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")

两个陷阱。扩展仅在的无头模式下加载——普通--headless会因“无法等待扩展后台页面”错误而失败,因此--headless=new是必需的。通过--load-extension加载未打包目录在不同Chrome版本中比打包zip更可靠。如果你不想维护这个,PyPI上的selenium-authenticated-proxy包可以从单个代理URL生成扩展。

四种Selenium代理认证方法的比较:IP白名单、Manifest V3扩展、selenium-wire和抓取API
当出口IP固定时,白名单胜出;在临时机器上,MV3扩展胜出;selenium-wire以MITM指纹交换便利性。

方法3:selenium-wire及其权衡

selenium-wire用本地中间人代理包装WebDriver,使得认证的上游代理——包括SOCKS5——成为简单的选项字典:

# pip install selenium-wire
from seleniumwire import webdriver

options = {
    "proxy": {
        "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
        "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
        "no_proxy": "localhost,127.0.0.1",
    }
}

driver = webdriver.Chrome(seleniumwire_options=options)
driver.get("https://httpbin.org/ip")

了解你在购买什么。该项目在2024年初由维护者存档,不再更新,并且因为它在本地解密流量,目标看到的是selenium-wire的TLS握手而不是Chrome的——即使你的IP完美无瑕,JA3/JA4指纹识别系统也会标记不匹配。它在开发期间用于请求检查和Firefox中非常有用,扩展技巧不存在。在受保护网站上的生产抓取中,优先使用方法1-2,或提升到更高层。

Firefox和认证差距

Firefox通过配置文件偏好设置(network.proxy.type = 1加上主机和端口设置)干净地接受未经认证的代理,但没有Chrome的扩展技巧来通过WebDriver回答凭证对话框。实际上,Firefox用户选择IP白名单或selenium-wire。如果你使用Firefox的唯一原因是其代理处理,这个原因不再成立。

何时停止修补Selenium并切换到API

认证是第一个税,不是最后一个。一个Chrome实例消耗数百MB的RAM,因此几十个并发会话就能让服务器饱和;ChromeDriver版本追逐Chrome发布;反机器人供应商无论背后IP如何都能检测到原生Selenium——navigator.webdriver和CDP工件暴露了它。两个升级改变了经济学。首先,通过住宅代理运行浏览器,这样IP声誉就不再是你被阻止的原因——9000万+家庭IP,支持每次请求轮换或登录流的粘性会话。其次,当维护浏览器不再值得时,一个Scraper API将整个堆栈压缩成一个HTTP调用:它按需渲染JavaScript,内部管理IP和重试,并返回HTML、markdown或结构化JSON。同样的权衡适用于Selenium的近亲——在假设框架切换能解决检测问题之前,请参阅我们关于Playwright代理集成Puppeteer代理设置的指南。

从Selenium代理白名单到Manifest V3扩展到住宅代理再到抓取API的升级阶梯
只爬到目标强迫你的高度:标志、扩展、更好的IP,然后让API运行浏览器。

常见问题解答

如何在Selenium ChromeDriver中设置带认证的代理?

要么在代理提供商处将机器的IP列入白名单,并传递一个简单的--proxy-server标志,要么加载一个小型Manifest V3扩展,通过chrome.webRequest.onAuthRequired设置代理并提供凭证。在标志中嵌入user:pass@不起作用——Chromium会忽略它。

为什么Chrome在Selenium中显示代理登录弹窗?

代理以407响应,Chrome要求人类输入凭证。对话框是本地UI,WebDriver不可见,因此没有选择器或send_keys调用可以填充它。解决方法是在对话框出现之前进行认证:IP白名单、认证扩展或像selenium-wire这样的MITM层。

selenium-wire在2026年还有效吗?

它仍然可以安装并在许多工作负载中运行,但项目在2024年初被存档,不再维护。其MITM设计也将Chrome的TLS指纹替换为Python的,现代反机器人系统会检测到。将其视为调试工具,而不是生产抓取器的基础。

如何在Selenium中使用带认证的Firefox代理?

Firefox配置文件偏好设置配置代理地址,但不能回答凭证提示,并且没有像Chrome那样的扩展解决方案。使用IP白名单,这样就不需要凭证,或者通过selenium-wire路由Firefox,它在本地处理上游认证。

这在Java和C#中是否相同?

是的——机制在Chrome中,而不是语言绑定中。IP白名单加--proxy-server在任何地方都是相同的,Manifest V3扩展方法通过编写相同的两个文件并将--load-extension添加到ChromeOptions中,从Java或C#中工作。只有selenium-wire是Python特有的;其他语言使用本地MITM代理,如BrowserMob。

简短版本:永远不要与认证对话框作斗争。当你的IP稳定时使用白名单,当不稳定时生成MV3扩展,保留selenium-wire用于检查工作——当浏览器维护超出其产生的数据时,将任务提升到API,享受你的夜晚。

在住宅IP上运行Selenium