在 Python 中为 Selenium 配置代理,需要通过浏览器专用选项传入代理设置,或者对需要认证的会话使用 Selenium-wire 这类中间件库。对于无需认证的标准 HTTP 或 SOCKS5 代理,ChromeOptions 中的 --proxy-server 参数是最高效的方式;而带认证的代理通常需要自定义浏览器扩展或支持代理的驱动。
为什么 Selenium 自动化必须集成代理
Selenium 是强大的网页自动化工具,但它的默认行为——从单一的静态 IP 地址发出请求——使其极易触发限流和 IP 封禁。在进行大规模数据抓取或跨地区自动化测试时,代理充当中间层,隐藏您的真实来源,并把请求分散到多个 IP 地址上。
使用 GProxy 这样的服务,可以获得住宅代理和数据中心代理池,避免网站把流量识别为来自单一自动化来源。这在以下场景尤为关键:
- 网页抓取:绕过 Cloudflare、Akamai 等按 IP 监控请求频率的反机器人机制。
- 本地化测试:验证网站为特定国家的用户显示了正确的货币、语言和内容。
- 广告核验:确保广告被正确投放给目标受众,没有被拦截或跳转。
- 压力测试:模拟来自不同地理位置的流量,测试服务器响应时间和 CDN 效率。

Chrome 和 Firefox 的基础代理配置
在 Selenium 中启用代理最直接的方式是使用浏览器原生选项。该方法最适合“IP 白名单”类代理:代理服务商(例如 GProxy)授权您服务器的 IP 地址,连接串中无需用户名和密码。
使用 Options 配置 Chrome
在 Chrome 中使用 add_argument 方法。这是最快的实现方式,对浏览器启动时间的额外开销可以忽略不计。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
proxy_ip_port = "gw.gproxy.com:10000"
chrome_options = Options()
chrome_options.add_argument(f'--proxy-server={proxy_ip_port}')
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://api.ipify.org?format=json")
print(driver.page_source)
driver.quit()
使用 Proxy 对象配置 Firefox
Firefox 处理代理的方式不同,通常使用 selenium.webdriver.common.proxy 中的 Proxy 对象。这样可以更精细地控制哪些协议(HTTP、SSL、SOCKS)走代理。
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
proxy_host = "gw.gproxy.com:10000"
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = proxy_host
proxy.ssl_proxy = proxy_host
options = webdriver.FirefoxOptions()
options.proxy = proxy
driver = webdriver.Firefox(options=options)
driver.get("https://httpbin.org/ip")
driver.quit()
在 Selenium 中处理代理认证
标准 Selenium 并不原生支持通过 --proxy-server 参数使用需要用户名和密码的代理。如果尝试使用 http://user:pass@host:port,Chrome 通常会忽略凭据,或弹出 Selenium 难以操作的浏览器原生弹窗。要解决这个问题,主要有两种专业做法。
方法一:使用 Selenium-wire
Selenium-wire 是 Selenium 的封装层,扩展了检查请求与响应的能力,更重要的是能透明地处理代理认证。它通过运行一个本地代理服务器来拦截流量并注入所需的认证头。
from seleniumwire import webdriver
# GProxy 凭据与接入点
proxy_options = {
'proxy': {
'http': 'http://username:[email protected]:10000',
'https': 'https://username:[email protected]:10000',
'no_proxy': 'localhost,127.0.0.1'
}
}
driver = webdriver.Chrome(seleniumwire_options=proxy_options)
driver.get("https://www.gproxy.com/check-ip")
driver.quit()
方法二:自定义扩展方案
在不希望承担 Selenium-wire 的 MITM(中间人)代理开销的高性能场景中,动态创建一个临时 Chrome 扩展是业界标准做法。该扩展使用 chrome.proxy API 设置凭据。
import os
import zipfile
from selenium import webdriver
def create_proxy_extension(proxy_host, proxy_port, proxy_user, proxy_pass):
manifest_json = """
{
"version": "1.0.0",
"manifest_version": 2,
"name": "GProxy Extension",
"permissions": [
"proxy",
"tabs",
"unlimitedStorage",
"storage",
"<all_urls>",
"webRequest",
"webRequestBlocking"
],
"background": {
"scripts": ["background.js"]
},
"minimum_chrome_version":"22.0.0"
}
"""
background_js = f"""
var config = {{
mode: "fixed_servers",
rules: {{
singleProxy: {{
scheme: "http",
host: "{proxy_host}",
port: parseInt({proxy_port})
}},
bypassList: ["localhost"]
}}
}};
chrome.proxy.settings.set({{value: config, scope: "regular"}}, function() {{}});
chrome.webRequest.onAuthRequired.addListener(
function(details) {{
return {{
authCredentials: {{
username: "{proxy_user}",
password: "{proxy_pass}"
}}
}};
}},
{{urls: ["<all_urls>"]}},
['blocking']
);
"""
extension_path = 'proxy_auth_plugin.zip'
with zipfile.ZipFile(extension_path, 'w') as zp:
zp.writestr("manifest.json", manifest_json)
zp.writestr("background.js", background_js)
return extension_path
# 具体实现
proxy_ext = create_proxy_extension("gw.gproxy.com", "10000", "my_user", "my_pass")
options = webdriver.ChromeOptions()
options.add_extension(proxy_ext)
driver = webdriver.Chrome(options=options)

代理配置方法对比
选择哪种方法,取决于您的性能要求、代理类型(住宅代理还是数据中心代理),以及是否需要频繁轮换 IP。
| 方法 | 认证支持 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| ChromeOptions | 仅 IP 白名单 | 优秀 | 低 | 静态数据中心 IP |
| Selenium-wire | 原生用户名/密码 | 中等(有额外开销) | 低 | 快速原型、调试 |
| 自定义扩展 | 原生用户名/密码 | 优秀 | 高 | 生产级抓取 |
| GProxy Backconnect | 单一接入点 | 优秀 | 低 | 大规模 IP 轮换 |
高级代理管理:轮换与粘性会话
使用 GProxy 时,您通常要在轮换代理和粘性会话之间做选择。了解如何在 Python 中实现它们,对于在结算流程或多步表单提交中保持会话连续性至关重要。
实现粘性会话
粘性会话可确保您的 Selenium 驱动实例发出的所有请求在设定时长内(例如 10 到 30 分钟)停留在同一个 IP 地址上。在 GProxy 中,这通常通过用户名字符串里的会话 ID 来实现。
# 使用 GProxy 住宅代理池的粘性会话示例
session_id = "session_82734"
proxy_user = f"user-customer_id-session-{session_id}"
# 然后在 Selenium-wire 或扩展配置中使用该用户名字符串
配合代理管理无头模式
在服务器端脚本中以无头模式(--headless)运行 Selenium 是常规做法。但无头 Chrome 有时会泄露您的真实 IP,或者无法加载扩展。如果您用扩展方式做认证,必须使用 Chrome 109+ 提供的新版无头模式,才能保证扩展被正确加载:
options.add_argument('--headless=new')
--headless=new 参数让浏览器环境更接近有界面的浏览器,从而提升代理认证的可靠性,并降低被高级反机器人脚本识别的概率。
常见代理问题排查
即使配置正确,Selenium 的代理方案仍可能出问题。以下是最常见的故障及其技术解决办法:
- ProxyConnectionError:通常是端口填错,或防火墙拦截了到代理服务商的出站连接。请确认 10000 端口(或服务商指定的端口)已放行。
- DNS 泄露:默认情况下 Selenium 仍可能通过本地 ISP 解析 DNS 查询。为避免这一点,尤其是在使用 SOCKS5 时,请确保浏览器被配置为通过代理执行 DNS 查询。
- 加载缓慢:住宅代理天然比数据中心代理慢。如果性能至关重要且您没有遭遇激进的 IP 封禁,请使用 GProxy 的数据中心代理池。
- 认证弹窗:如果出现登录弹窗,说明您的认证方式(扩展或 Selenium-wire)失败了,或者没有在第一次请求之前完成初始化。
关键要点
在 Selenium 中配置代理是一个分层的过程。简单的 IP 白名单代理可以通过命令行参数搞定,而带认证的住宅代理则需要自定义扩展或 Selenium-wire 这类更稳健的方案。
- 使用 GProxy Backconnect:与其在 Python 代码里维护一份 10,000 个 IP 的清单,不如使用 GProxy 提供的单一 backconnect 接入点自动完成轮换。
- 优先选择扩展方案:在生产环境中,Chrome 扩展方式优于 Selenium-wire,因为它不引入第二层代理,延迟更低。
- 监控成功率:始终把
driver.get()调用包在 try-except 中以捕获WebDriverException,让脚本在某个代理节点失效时更换会话 ID 并重试。
