且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用Selenium 3启动特定的Firefox配置文件

更新时间:2022-03-12 22:42:59

此异常是由于中的错误所致。网络图书馆。

This exception is due to a bug in the .Net library. The code generating the Zip of the profile is failing to provide a proper Zip.

一种解决此问题的方法是重载 FirefoxOptions

One way to overcome this issue would be to overload FirefoxOptions and use the archiver from .Net framework (System.IO.Compression.ZipArchive) instead of the faulty ZipStorer:

var options = new FirefoxOptionsEx();
options.Profile = @"C:\Users\...\AppData\Roaming\Mozilla\Firefox\Profiles\ez3krw80.Selenium";
options.SetPreference("network.proxy.type", 0);

var service = FirefoxDriverService.CreateDefaultService(@"C:\downloads", "geckodriver.exe");

var driver = new FirefoxDriver(service, options, TimeSpan.FromMinutes(1));





class FirefoxOptionsEx : FirefoxOptions {

    public new string Profile { get; set; }

    public override ICapabilities ToCapabilities() {

        var capabilities = (DesiredCapabilities)base.ToCapabilities();
        var options = (IDictionary)capabilities.GetCapability("moz:firefoxOptions");
        var mstream = new MemoryStream();

        using (var archive = new ZipArchive(mstream, ZipArchiveMode.Create, true)) {
            foreach (string file in Directory.EnumerateFiles(Profile, "*", SearchOption.AllDirectories)) {
                string name = file.Substring(Profile.Length + 1).Replace('\\', '/');
                if (name != "parent.lock") {
                    using (Stream src = File.OpenRead(file), dest = archive.CreateEntry(name).Open())
                        src.CopyTo(dest);
                }
            }
        }

        options["profile"] = Convert.ToBase64String(mstream.GetBuffer(), 0, (int)mstream.Length);

        return capabilities;
    }

}

并按名称获取配置文件的目录:

And to get the directory for a profile by name:

var manager = new FirefoxProfileManager();
var profiles = (Dictionary<string, string>)manager.GetType()
    .GetField("profiles", BindingFlags.Instance | BindingFlags.NonPublic)
    .GetValue(manager);

string directory;
if (profiles.TryGetValue("Selenium", out directory))
    options.Profile = directory;