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

标签 c# .net selenium firefox selenium-webdriver

我正在尝试从 Selenium 2 升级到 Selenium 3,但是非常简单和快速的旧处理方式不再有效(而且文档似乎不存在)

这是目前的程序,我想要打开配置文件为 SELENIUM 的 Firefox 驱动程序

很遗憾,它不起作用,并且总是因错误而关闭:

An unhandled exception of type 'System.InvalidOperationException' > occurred in WebDriver.dll

Additional information: corrupt deflate stream

这是我目前的程序:

public Program()
{
    FirefoxOptions _options = new FirefoxOptions();
    FirefoxProfileManager _profileIni = new FirefoxProfileManager();
    FirefoxDriverService _service = FirefoxDriverService.CreateDefaultService(@"C:\Programme\IMaT\Output\Release\Bin");
    _service.FirefoxBinaryPath = @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
    try
    {
        if ((_options.Profile = _profileIni.GetProfile("SELENIUM")) == null)
        {
            Console.WriteLine("SELENIUM PROFILE NOT FOUND");
            _profile.SetPreference("network.proxy.type", 0); // disable proxy
            _profile = new FirefoxProfile();
        }
    }
    catch
    {
        throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
    }
    IWebDriver driver = new FirefoxDriver(_service,_options,new System.TimeSpan(0,0,30));        
    driver.Navigate().GoToUrl("ld-hybrid.fronius.com");
    Console.Write("rtest");
}

static void Main(string[] args)
{
    new Program();
}

在不加载配置文件的情况下,它仅适用于新的 FirefoxDriver(_service),但配置文件是强制性的。

在 Selenium 2 中,我用这段代码处理了它:

FirefoxProfileManager _profileIni = new FirefoxProfileManager();
// use custom temporary profile
try { 
    if ((_profile = _profileIni.GetProfile("SELENIUM")) == null)
    {
        Console.WriteLine("SELENIUM PROFILE NOT FOUND");
        _profile.SetPreference("network.proxy.type", 0); // disable proxy
        _profile = new FirefoxProfile();
    }
}
catch
{
    throw new Exception("Firefox needs a Profile with \"SELENIUM\"");
}

_profile.SetPreference("intl.accept_languages", _languageConfig);
_driver = new FirefoxDriver(_profile);

快速而简单,但由于驱动程序不支持具有服务和配置文件的构造函数,我真的不知道如何让它工作,任何帮助将不胜感激

最佳答案

此异常是由于 .Net 库中的错误。生成配置文件 Zip 的代码无法提供正确的 Zip。

解决此问题的一种方法是重载 FirefoxOptions 并使用 .Net 框架 (System.IO.Compression.ZipArchive) 中的存档程序而不是有问题的 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;
    }

}

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

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;

关于c# - 使用 Selenium 3 启动特定的 Firefox 配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43253372/

相关文章:

javascript - Scrapy-Selenium 纽约时报问题

c# - 在 Table<> 上的 Lambda Where() 中使用联接的任何方法?

c# - System.Runtime.Caching.MemoryCache 在被逐出时会处理 IDisposable 项目吗?

.net - 如何限制Azure临时环境访问资源

java - 找到复选框并添加文本

javascript - 实习生功能测试 - 按顺序单击一组按钮

c# - Visual Studio 2017 意外字符 '

c# - 可以将 "async"与 ThreadStart 方法一起使用吗?

c# - 每天午夜在 .Net Core 3.0 中运行 BackgroundService

.net - 如何读取XML文件的所有子节点