当元素已经存在时,如何停止在Selenium WebDriver中加载页面?

时间:2016-10-13 04:56:40

标签: c# selenium-webdriver phantomjs

我正在抓一个网站,由于某种原因需要15秒加载,但我需要的元素在前5秒内加载。

问题是,我可以停止加载页面,并在代码已经存在时继续使用代码吗?

当前代码:

driver.Navigate().GoToUrl(url);

new WebDriverWait(driver, TimeSpan.FromSeconds(20))
    .Until(ExpectedConditions.ElementIsVisible(By.XPath(xpath)));

当前行为:

  1. 我致电driver.Navigate().GoToUrl(url);
  2. 驱动程序开始加载页面
  3. 元素存在于约。 5秒(那时我想继续下一个声明)
  4. 驱动程序等待整整15秒才能完全加载页面
  5. 然后驱动程序最终移动到WebDriverWait函数
  6. 问题:

    类似问题的所有解决方案都是在页面完全加载后调用的,这使得答案毫无用处。

    我能为此做些什么吗?谢谢。

2 个答案:

答案 0 :(得分:3)

方法.Navigate()。GoToUrl的创建方式是只有在页面完全加载时才执行下一行。所以,是的,你在代码中编写什么并不重要,在导航方法之后,它将永远不会工作,直到页面完全加载。 作为一种解决方法,您可以选择超时选项,这将导致异常,因为页面仍然需要加载,因此我们应该捕获并执行下一个代码。

//这是java代码,所以请从这里选择逻辑:
//将页面加载超时设置为10秒。

 Connection connection = null;
          while (connection == null && count<3){
            try {

                  String Connection="jdbc:sqlserver://"+serverip+';'+"database="+dbName+';'+"user=" +Username+';'+"password=" +Password;
                  Class.forName(classname); 
                  connection = DriverManager.getConnection(Connection); 

                }catch (SQLException e){
                    count++;
                    System.err.println("Connecting failed, retrying...");
            }
          }
          count=0;  
          return connection;                  
        }

答案 1 :(得分:1)

我遇到了同样的问题并且搜索过很多但是没有找到可行的解决方案。超时解决方案不适用于我的情况。最后,似乎真正有效的唯一方法是使用全局钩子。

有关钩子的更多信息,请参阅这篇优秀的帖子:Global keyboard capture in C# application

因此,在从上面链接获取的钩子处理代码中,添加如下内容:

    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            if (vkCode == 121)  //F10 key
            {
                try
                {
                    UnhookWindowsHookEx(_hookID);//avoid ESC key to be captured
                    SetForegroundWindow(_handle);
                    SendKeys.Send("{ESC}");
                    _hookID = SetHook(_proc);

                }
                catch (Exception ex)
                {
                }
            }
        }

        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

以下相关代码:

    using System.Windows.Automation; //you need to reference UIAutomationClient and UIAutomationTypes

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    private IntPtr _handle;

    //I forget where I got the code of the function below, probably also from stackoverflow. Thanks to the original author!
    private IntPtr getIntPtrHandle(IWebDriver driver, int timeoutSeconds = 30)
    {
        var end = DateTime.Now.AddSeconds(timeoutSeconds);
        while (DateTime.Now < end)
        {
            // Searching by AutomationElement is a bit faster (can filter by children only)
            var ele = AutomationElement.RootElement;
            foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
            {
                if (!child.Current.Name.Contains(driver.Title)) continue;
                return new IntPtr(child.Current.NativeWindowHandle); ;
            }
        }
        return IntPtr.Zero;
    }

还放_handle = getIntPtrHandle(webdriver);在您的webdriver.Navigate()。GoToUrl()语句之前的某处。

我测试了以上内容。在执行GoToUrl之后,在某处按F10(有时两次),页面停止加载。