通过Selenium关闭代理身份验证弹出窗口

时间:2015-01-29 15:11:45

标签: c# selenium proxy automation

我在一个阻止社交媒体网站的地方工作,并为那些有合法商业理由去找他们的(少数)人弹出代理登录。由于大多数网站都有Facebook,Twitter或类似链接,因此代理提示相当多。当以正常的,以人为本的方式浏览时,我只需按ESC键即可摆脱代理登录对话。我怎么能通过Selenium这样做?我已经看过很多关于关闭ALERT消息或模态对话的帖子和解决方案,但我还没有看到关闭代理登录的任何内容;只是通过提供凭据绕过它。

任何帮助/提示将不胜感激。谢谢!

规格: 我在C#

中使用Selenium 2.44和Firefox驱动程序

编辑#2:关于此对话的更多信息)

此登录提示来自我们自己的内部代理服务器。我们的代理服务器基本上是在询问用户是否有权在与远程站点进行任何通信之前访问所请求的站点。只要元素在远程站点上,它就会弹出。因此,例如,如果一个站点有一个Facebook和Twitter按钮从Facebook或Twitter本身拉出按钮,用户将看到两个代理登录提示。虽然页面的其他元素会在等待时加载,但页面加载过程最终会等待任何自动阻止的元素的答案。

我解决此问题的一种方法是将Firefox驱动程序与NoScript结合使用,并从白名单中删除所有社交网络链接。这是一个粗略的解决方法,并强制使用一个浏览器。我正在寻找的是Selenium通过代码简单地关闭代理登录提示的方式(如果这样做的话)。

修改:已添加屏幕截图示例) enter image description here

修改:从Inspect添加了截图) Screenshot from Inspect of proxy window

2 个答案:

答案 0 :(得分:2)

导航到这样的网站:

WebDriver.Navigate().GoToUrl("http://username:password@website.com");

website.com将是通常的网站。

如果您不想登录,可以使用Action将Escape键发送给驱动程序:

var action = new Actions(WebDriver);
action.SendKeys(Keys.ESCAPE).Build().Perform();

答案 1 :(得分:1)

不确定硒,但您可以使用System.Windows.Automation命名空间。

  1. 订阅顶级窗口
  2. 使用收到的AutomationElement来检查它是否与您的Firefox窗口信息相符(您可以使用类似Inspect的内容来了解​​它们是什么)
  3. 使用上面的AutomationElement订阅子窗口已打开事件
  4. 在事件上,检查它是否是代理弹出窗口
  5. 使用close方法或SendKeys发送ESC
  6. 这是一个示例代码,您必须收集窗口的类名,自动化ID和名称(随意表达,我将编辑答案):

    using System.Linq;
    using System.Text.RegularExpressions;
    using System.Windows.Automation;
    
    namespace FirefoxAutomation
    {
        class FirefoxAutomation
        {
            private const string FF_CLASSNAME = "MozillaWindowClass"; //"Firefox ClassName taken from Inspect";
            private const string FF_AUTOMATIONID = null;//"Firefox AutomationId taken from Inspect";
            private static readonly Regex FF_NAME = new Regex("( - Mozilla Firefox)$"); //new Regex("Firefox Name regex based on name taken from Inspect");
    
            private const string PROXY_CLASSNAME = "MozillaDialogClass";//"Proxy window ClassName taken from Inspect";
            private const string PROXY_AUTOMATIONID = null;//"Proxy window AutomationId taken from Inspect";
            private static readonly Regex PROXY_NAME = new Regex("^(Authentication Required)$");//new Regex("Proxy window Name regex based on name taken from Inspect");
    
            public FirefoxAutomation()
            {
                SubscribeTopLevelWindowOpened();
            }
    
            private void SubscribeTopLevelWindowOpened()
            {
                Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
                    AutomationElement.RootElement, TreeScope.Children, TopLevelWindowOpened);
            }
    
            private void TopLevelWindowOpened(object sender, AutomationEventArgs e)
            {
                var element = sender as AutomationElement;
                if (element == null) return;
    
                // Filter for FireFox window element
                if (!MatchWindow(element, FF_CLASSNAME, FF_AUTOMATIONID, FF_NAME)) return;
    
                // Subscribe for child window opened even
                Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent,
                    element, TreeScope.Children, FireFoxChildWindowOpened);
            }
    
            private void FireFoxChildWindowOpened(object sender, AutomationEventArgs e)
            {
                var element = sender as AutomationElement;
                if (element == null) return;
    
                // Filter for a proxy message
                if (!MatchWindow(element, PROXY_CLASSNAME, PROXY_AUTOMATIONID, PROXY_NAME)) return;
    
                // Find the cancel button
                var controls = element.FindAll(TreeScope.Children, Condition.TrueCondition).Cast<AutomationElement>().ToList();
                var cancelButton = controls.FirstOrDefault(c => c.Current.ControlType == ControlType.Button && c.Current.Name == "Cancel");
                if (cancelButton == null) return;
    
                // Get the click pattern
                object clickPatternObj;
                if (!cancelButton.TryGetCurrentPattern(InvokePattern.Pattern, out clickPatternObj)) return;
                ((InvokePattern)clickPatternObj).Invoke(); // click the cancel button
            }
    
            private bool MatchWindow(AutomationElement element, string className, string automationId, Regex name)
            {
                var current = element.Current;
                if (current.ControlType != ControlType.Window) return false;
                if (className != null && current.ClassName != className) return false;
                if (automationId != null && current.AutomationId != automationId) return false;
                if (name != null && name.IsMatch(current.Name)) return false;
                return true;
            }
        }
    }