如何将现有配置文件与 Selenium Webdriver 一起使用?

gro*_*ber 7 python firefox selenium-webdriver

我正在尝试使用 Python 的Selenium Webdriver以及Firefox位于<PROFILE-DIR>.

我尝试过的

#!/usr/bin/env python

from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
from selenium.webdriver import Firefox, DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options

options = Options()
options.profile = '<PROFILE_DIR>'
webdriver = Firefox(options=options)
Run Code Online (Sandbox Code Playgroud)

这会将现有配置文件复制到临时位置。我可以看到它有效,因为我启动的新会话可以访问配置文件的旧cookie等。但这不是我想要的:我想就地使用配置文件。

  • 尝试将配置文件作为“--profile”传递给args功能:将上面的代码更改为
capabilities = DesiredCapabilities.FIREFOX.copy()
capabilities['args'] = '--profile <PROFILE-DIR>'
webdriver = Firefox(desired_capabilities=capabilities)
Run Code Online (Sandbox Code Playgroud)

什么也没做:关闭会话后查看geckodriver.log仍然显示类似的内容Running command: "/usr/bin/firefox" "--marionette" "-foreground" "-no-remote" "-profile" "/tmp/rust_mozprofileOFKY46",即仍在使用临时配置文件(它甚至不是现有配置文件的副本;旧的 cookie 不在那里)。

  • 尝试使用相反的capabilities['args'] = ['-profile', '<PROFILE-DIR>']方法(即字符串列表而不是单个字符串);相同的结果。

  • 读了很多其他的SO帖子,但没有一个能做到这一点。这主要是因为它们是特定于的Chrome(您显然可以向其驱动程序传递命令行选项;我还没有看到类似的东西geckodriver),或者因为它们回退到现有配置文件的副本。

在这个方向上最相关的答案基本上实现了我想到的相同的黑客,在紧要关头:

  1. options.profile如上所述,使用您现有配置文件的副本启动驱动程序;

  2. 完成后手动关闭驱动程序实例(例如使用Ctrl+C, 或SIGINT),以便临时配置文件目录不会被删除;

  3. 复制现有配置文件顶部留下的所有内容,使您可以访问自动化会话中所需的任何剩余内容。

这很丑陋并且感觉没有必要。此外,geckodriver未能删除临时配置文件(我所依赖的)被认为是一个错误。

当然,我误解了如何传递上面提到的这些功能选项,或者类似的东西。但文档可以在举例方面做得更好。

ple*_* me 1

我提出了一个解决方案,允许用户通过环境变量动态地将配置文件路径传递给 Geckodriver,从而就地使用 Firefox 配置文件。

我首先下载Geckodriver 0.32.0,这样您只需通过环境变量提供 Firefox 配置文件目录即可FIREFOX_PROFILE_DIR

代码更改位于src/browser.rs第 88 行,替换:

    let mut profile = match options.profile {
        ProfileType::Named => None,
        ProfileType::Path(x) => Some(x),
        ProfileType::Temporary => Some(Profile::new(profile_root)?),
    };
Run Code Online (Sandbox Code Playgroud)

和:

    let mut profile = if let Ok(profile_dir) = std::env::var("FIREFOX_PROFILE_DIR") {
        Some(Profile::new_from_path(Path::new(&profile_dir))?)
    } else {
        match options.profile {
            ProfileType::Named => None,
            ProfileType::Path(x) => Some(x),
            ProfileType::Temporary => Some(Profile::new(profile_root)?),
        }
    };
Run Code Online (Sandbox Code Playgroud)

您可以参考我的Git 提交来查看与原始 Geckodriver 代码的差异。