2021年5月30日更新的帖子
这是我在Stack Overflow上尝试回答过的最困难的问题,因为它涉及到多个用不同编程语言(Java、Rust和C++)编写的代码库之间的交互。这种复杂性使得这个问题可能无法解决。
这是我对这个可能无法解决的问题的最后尝试:
在你的问题中的代码中,你正在修改user.js文件。这个文件仍然被Selenium使用。
public FirefoxProfile() {
this(null);
}
public FirefoxProfile(File profileDir) {
this(null, profileDir);
}
@Beta
protected FirefoxProfile(Reader defaultsReader, File profileDir) {
if (defaultsReader == null) {
defaultsReader = onlyOverrideThisIfYouKnowWhatYouAreDoing();
}
additionalPrefs = new Preferences(defaultsReader);
model = profileDir;
verifyModel(model);
File prefsInModel = new File(model, "user.js");
if (prefsInModel.exists()) {
StringReader reader = new StringReader("{\"frozen\": {}, \"mutable\": {}}");
Preferences existingPrefs = new Preferences(reader, prefsInModel);
acceptUntrustedCerts = getBooleanPreference(existingPrefs, ACCEPT_UNTRUSTED_CERTS_PREF, true);
untrustedCertIssuer = getBooleanPreference(existingPrefs, ASSUME_UNTRUSTED_ISSUER_PREF, true);
existingPrefs.addTo(additionalPrefs);
} else {
acceptUntrustedCerts = true;
untrustedCertIssuer = true;
}
loadNoFocusLib = false;
try {
defaultsReader.close();
} catch (IOException e) {
throw new WebDriverException(e);
}
}
理论上来说,您应该能够修改capabilities.rs在geckodriver源代码中。该文件包含了temp_dir。
正如我之前所述,这只是一种理论,因为当我查看Firefox源代码时,其中遍布着temp_dir。
原始帖子 2021年5月26日
我不确定你能否阻止Selenium创建临时的Firefox配置文件。
根据gecko文档:
"配置文件会被创建在系统的临时文件夹中。当提供了配置文件时,编码的配置文件也会被提取到这个位置。默认情况下,geckodriver会在这个位置创建一个新的配置文件。"
目前我看到的唯一解决方案需要你修改Geckodriver源代码以阻止临时文件夹/配置文件的创建。
我正在查看源代码。这些文件可能是正确的,但我需要进一步查看源代码:
以下是需要仔细查看的其他文件:
https://searchfox.org/mozilla-central/search?q=tempfile&path=
这看起来很有前途。
https://searchfox.org/mozilla-central/source/testing/geckodriver/doc/Profiles.md
geckodriver使用[配置文件]来操纵Firefox的行为。用户通常会依赖geckodriver生成一个临时的、一次性的配置文件。这些配置文件在WebDriver会话过期时被删除。
在用户需要使用自定义的预先准备好的配置文件的情况下,geckodriver会对配置文件进行修改以确保正确的行为。请参阅下面关于用户定义偏好设置的优先级的[自动化偏好设置]。
可以通过两种不同的方式提供自定义配置文件:
1. 通过将`--profile /some/location`附加到[args capability],这将指示geckodriver在原地使用该配置文件;
我在尝试这样做时找到了一个相关问题:
如何在Selenium Webdriver中原地使用现有配置文件?
此外,这是一个在Selenium的Github上提出的关于临时目录的问题:
https://github.com/SeleniumHQ/selenium/issues/8645
在查看
geckodriver v0.29.1的源代码时,我发现了一个加载配置文件的文件。
源代码:capabilities.rs
fn load_profile(options: &Capabilities) -> WebDriverResult<Option<Profile>> {
if let Some(profile_json) = options.get("profile") {
let profile_base64 = profile_json.as_str().ok_or_else(|| {
WebDriverError::new(ErrorStatus::InvalidArgument, "Profile is not a string")
})?;
let profile_zip = &*base64::decode(profile_base64)?;
let profile = Profile::new()?;
unzip_buffer(
profile_zip,
profile
.temp_dir
.as_ref()
.expect("Profile doesn't have a path")
.path(),
)?;
Ok(Some(profile))
} else {
Ok(None)
}
}
来源:marionette.rs
fn start_browser(&mut self, port: u16, options: FirefoxOptions) -> WebDriverResult<()> {
let binary = options.binary.ok_or_else(|| {
WebDriverError::new(
ErrorStatus::SessionNotCreated,
"Expected browser binary location, but unable to find \
binary in default location, no \
'moz:firefoxOptions.binary' capability provided, and \
no binary flag set on the command line",
)
})?;
let is_custom_profile = options.profile.is_some();
let mut profile = match options.profile {
Some(x) => x,
None => Profile::new()?,
};
self.set_prefs(port, &mut profile, is_custom_profile, options.prefs)
.map_err(|e| {
WebDriverError::new(
ErrorStatus::SessionNotCreated,
format!("Failed to set preferences: {}", e),
)
})?;
let mut runner = FirefoxRunner::new(&binary, profile);
runner.arg("--marionette");
if self.settings.jsdebugger {
runner.arg("--jsdebugger");
}
if let Some(args) = options.args.as_ref() {
runner.args(args);
}
runner
.env("MOZ_CRASHREPORTER", "1")
.env("MOZ_CRASHREPORTER_NO_REPORT", "1")
.env("MOZ_CRASHREPORTER_SHUTDOWN", "1");
let browser_proc = runner.start().map_err(|e| {
WebDriverError::new(
ErrorStatus::SessionNotCreated,
format!("Failed to start browser {}: {}", binary.display(), e),
)
})?;
self.browser = Some(Browser::Host(browser_proc));
Ok(())
}
pub fn set_prefs(
&self,
port: u16,
profile: &mut Profile,
custom_profile: bool,
extra_prefs: Vec<(String, Pref)>,
) -> WebDriverResult<()> {
let prefs = profile.user_prefs().map_err(|_| {
WebDriverError::new(
ErrorStatus::UnknownError,
"Unable to read profile preferences file",
)
})?;
for &(ref name, ref value) in prefs::DEFAULT.iter() {
if !custom_profile || !prefs.contains_key(name) {
prefs.insert((*name).to_string(), (*value).clone());
}
}
prefs.insert_slice(&extra_prefs[..]);
if self.settings.jsdebugger {
prefs.insert("devtools.browsertoolbox.panel", Pref::new("jsdebugger"));
prefs.insert("devtools.debugger.remote-enabled", Pref::new(true));
prefs.insert("devtools.chrome.enabled", Pref::new(true));
prefs.insert("devtools.debugger.prompt-connection", Pref::new(false));
}
prefs.insert("marionette.log.level", logging::max_level().into());
prefs.insert("marionette.port", Pref::new(port));
prefs.write().map_err(|e| {
WebDriverError::new(
ErrorStatus::UnknownError,
format!("Unable to write Firefox profile: {}", e),
)
})
}
}
在查看了gecko源代码之后,我发现
mozprofile::profile::Profile是来自FireFox而不是geckodriver。
似乎在迁移到Selenium 4时,您可能会遇到配置文件的问题。
参考:
https://github.com/SeleniumHQ/selenium/issues/9417
对于Selenium 4,我们已经弃用了配置文件的使用,因为我们有其他机制可以加快启动速度。
请使用Options类来设置您需要的首选项,如果需要使用插件,请使用driver.install_addon("path/to/addon")安装插件。
您可以通过pip install selenium --pre安装Selenium 4(测试版)。
我注意到你的代码中写了一个
user.js文件,这是为FireFox定制的文件。你有没有考虑过在Gecko之外手动创建这些文件呢?
另外,你有没有看过
mozprofile?