Skip to content

解决 WebDriver.init() 中 'options' 参数重复传递错误

问题描述

在使用 Selenium 控制 Chrome 浏览器时,开发者常遇到以下错误:

python
TypeError: WebDriver.__init__() got multiple values for argument 'options'

此错误通常出现在类似下面的代码中:

python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

browser = webdriver.Chrome(r'/usr/bin/chromedriver', options=chrome_options)

错误堆栈明确显示问题发生在 WebDriver.__init__() 方法中:

TypeError                                 Traceback (most recent call last)
<ipython-input-5-9a7e59e392ae> in <cell line: 6>()
      4 chrome_options.add_argument('--headless')
      5 
----> 6 browser = webdriver.Chrome(r'/usr/bin/chromedriver', options=chrome_options)

TypeError: WebDriver.__init__() got multiple values for argument 'options'

错误原因

Selenium 4.10.0 行为变更

此错误源于 Selenium 4.10.0 版本的 API 变更(提交记录):

  1. 旧版webdriver.Chrome() 的第一个位置参数是 executable_path

    python
    # Selenium 4.10.0 之前的写法
    driver = webdriver.Chrome('/path/to/chromedriver', options=chrome_options)
  2. 新版webdriver.Chrome() 的第一个位置参数变为 options

    python
    # Selenium 4.10.0 及之后的默认行为
    driver = webdriver.Chrome(options=chrome_options)  # 此时第一个参数应是options

当同时以位置参数形式传入路径和关键字参数形式传入 options 时,会导致 options 参数被重复赋值,引发冲突报错。

解决方案

方法1:使用 Service 对象(推荐)

官方推荐方式

这是 Selenium 官方文档推荐的标准方法,适用于需要精确控制环境的场景:

python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service  # 导入Service模块
from selenium.webdriver.chrome.options import Options

# 创建Service对象指定驱动路径
service = Service(executable_path=r'/usr/bin/chromedriver')

# 配置浏览器选项
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

# 同时传入service和options
driver = webdriver.Chrome(service=service, options=chrome_options)

# 使用完毕后关闭浏览器
driver.quit()

关键要点:

  1. 通过 Service 对象封装 ChromeDriver 路径
  2. 使用关键字参数明确传递 serviceoptions
  3. 兼容 Selenium 4.10.0+ 的所有版本

方法2:自动安装 ChromeDriver

自动化环境适用

适合需要简化部署的场合,例如 Google Colab 或 Docker 环境:

python
!pip install chromedriver-autoinstaller  # 先安装自动管理工具

import chromedriver_autoinstaller
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# 自动检测并安装合适的ChromeDriver
chromedriver_autoinstaller.install()

# 配置浏览器选项
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

# 无需指定路径,直接初始化
driver = webdriver.Chrome(options=chrome_options)

# 正常使用浏览器...
driver.get("https://www.example.com")

# 使用完毕后关闭
driver.quit()

优势特点:

  • 自动处理 ChromeDriver 版本匹配问题
  • 无需手动管理驱动路径
  • 特别适合动态环境(如云服务器、Jupyter 环境)

Windows 系统注意事项

当在 Windows 系统中使用方案1时,注意添加 .exe 后缀:

python
from selenium.webdriver.chrome.service import Service

# 注意添加.exe后缀
service = Service(executable_path=r'..\chromedriver.exe')

解决方案对比

方案适用场景优势注意事项
Service对象生产环境、固定路径精确控制路径,官方标准方案需手动管理驱动版本
自动安装快速原型、云环境自动版本管理,简化部署依赖额外包(chromedriver_autoinstaller)

根本原因总结

Selenium 4.10.0 的重构改变了 webdriver.Chrome() 构造函数的参数结构:

  • 旧签名:Chrome(executable_path, options, ...)
  • 新签名:Chrome(options, service, ...)

若不更新代码,位置参数会错误解析为 options,而显式传递的 options 参数会造成冲突,引发报错。

最佳实践建议

  1. 明确声明参数:始终使用关键字参数传递配置

    python
    # 推荐(清晰明确)
    driver = webdriver.Chrome(service=service, options=options)
  2. 检查 Selenium 版本:使用以下命令检查版本

    bash
    pip show selenium
    # 或
    python -m pip show selenium
  3. 迁移策略

    diff
    - driver = webdriver.Chrome('/path', options=opts)
    + driver = webdriver.Chrome(service=Service('/path'), options=opts)

遵循以上方案可彻底解决 multiple values for argument 'options' 错误,并确保代码兼容最新版 Selenium。