Selenium WebDriver - 如何使用 C# 设置页面加载超时

Posted

技术标签:

【中文标题】Selenium WebDriver - 如何使用 C# 设置页面加载超时【英文标题】:Selenium WebDriver - How to set Page Load Timeout using C# 【发布时间】:2012-05-23 07:36:33 【问题描述】:

我正在使用 Selenium 2.20 WebDriver 创建和管理带有 C# 的 firefox 浏览器。要访问一个页面,我使用以下代码,在访问 URL 之前设置驱动程序超时:

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 0, 5));  // Set script timeouts to 5 secs
driver.Navigate().GoToUrl(myUrl);   // Goto page url

问题是有时页面加载需要很长时间,而且使用 selenium WebDriver 加载页面的默认超时似乎是 30 秒,这太长了。而且我不相信我设置的超时适用于使用 GoToUrl() 方法加载页面。

所以我试图弄清楚如何设置页面加载超时,但是,我找不到任何实际有效的属性或方法。当我点击一个元素时,默认的 30 秒超时似乎也适用。

有没有办法将页面加载超时设置为特定值,这样当我调用 GoToUrl() 方法时,它只会等待我指定的时间才能继续?

【问题讨论】:

您确定GoToUrl() 等待页面加载吗?我的经验是不会。但这只是一种感觉,而不是事实。 是的,我 100% 确定调用 GoToUrl() 会阻止执行,直到页面完全加载完成,并且我测量了调用此方法的默认超时 30 秒,30 秒后执行将继续,我正在尝试以某种方式减少 30 秒的默认超时时间。 我已经发布了类似的问题:***.com/questions/11958701/… @TorbjörnKalin 它确实会阻塞,直到页面加载到浏览器抛出 onReady 事件为止。如果有 post js 和 ajax ......那“页面加载”知识没有任何意义。 【参考方案1】:
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);

注意:driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5)) 现已弃用。

【讨论】:

你知道默认值大概是多少吗?【参考方案2】:

如果这有助于任何仍在寻找答案的人,C# WebDriver API 现在包含适当的方法。

driver.Manage().Timeouts().SetPageLoadTimeout(timespan)

【讨论】:

我只是希望有人能清楚地说明页面加载超时与隐式等待有何不同。页面到底什么时候加载,而一个元素不加载? 来自C#智能感知ImplicitlyWait是在页面上搜索一个元素的时间量,SetPageLoadTimeout是等待一个URL加载的时间量,SetScriptTimeout是量等待异步 JS 加载的时间。【参考方案3】:

有了这个,你应该能够明确声明等待。

WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(time in seconds));
wait.until(Your condition)

您也可以更改隐式等待时间

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));

我认为这是 C# 中的语法。 (不确定)

在红宝石中是

@driver.manage.timeouts.implicit_wait = 30
@wait = Selenium::WebDriver::Wait.new(:timeout => 30)

【讨论】:

这不起作用,因为执行被 GoToUrl() 方法阻止,所以在该方法完成或超时之前我无法执行任何代码,默认值似乎是 30 秒。不过感谢您的回复。 因此您需要更改您的隐式等待时间 - driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); 将 5 秒减少到您想要的更少。这会影响您在 gotourl 上的等待时间。 您也可以尝试wait.until (driver.Navigate().GoToUrl(myUrl)); // Goto page url,在其中明确定义等待执行 gotoURL 命令的时间 @seleniumnewbie:我不知道为什么有人支持wait.until (driver.Navigate().GoToUrl(myUrl)); // Goto page url,但从我得到的结果来看,这根本不起作用。【参考方案4】:

我找到了这个问题的解决方案。在创建新的 FirefoxDriver 时,构造函数中有重载,允许您指定命令超时,这是等待每个命令的最长时间,并且在调用 GoToUrl() 方法时似乎可以正常工作:

driver = new FirefoxDriver(new FirefoxBinary(), profile, new TimeSpan(0, 0, 0, timeoutSeconds));

链接到 FirefoxDriver 构造函数文档以供参考: http://selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/M_OpenQA_Selenium_Firefox_FirefoxDriver__ctor_2.htm

希望这可以帮助遇到此问题的其他人。

【讨论】:

我已经发布了类似的问题:***.com/questions/11958701/…【参考方案5】:

页面加载超时尚未在 .NET 绑定中实现。希望他们很快就会到来。

【讨论】:

这有什么更新吗? 9年过去了,它们似乎仍未实施。无论我在 ImplicitWait、Asynchronousjavascript 或 PageLoad 上设置什么超时,我的系统在 10 秒后仍然超时。【参考方案6】:

截至 2018 年: 除了这些:

driver.Manage().Timeouts().ImplicitWait.Add(System.TimeSpan.FromSeconds(5));      
driver.Manage().Timeouts().PageLoad.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().AsynchronousJavaScript.Add(timespan));

分别等待搜索项目、加载页面和等待脚本。 有:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));

【讨论】:

【参考方案7】:

我们巴西人对糟糕的解决方法有一个词“Gambiarra”......嗯......至少他们做到了...... 这是我的:

var url = "www.your.url.here"
try 
    DRIVER.Navigate().GoToUrl(url);
 catch 
    // Here you can freely use the Selenium's By class:
    WaitElement(By.Id("element_id_or_class_or_whatever_to_be_waited"), 60);

// rest of your application

我的WaitElement(By, int) 做了什么:

/// <summary>
/// Waits until an element of the type <paramref name="element"/> to show in the screen.
/// </summary>
/// <param name="element">Element to be waited for.</param>
/// <param name="timeout">How long (in seconds) it should be waited for.</param>
/// <returns>
/// False: Never found the element. 
/// True: Element found.
/// </returns>
private bool WaitElement(By element, int timeout)

    try 
        Console.WriteLine($" - Waiting for the element element.ToString()");
        int timesToWait = timeout * 4; // Times to wait for 1/4 of a second.
        int waitedTimes = 0; // Times waited.
        // This setup timesout at 7 seconds. you can change the code to pass the 

        do 
            waitedTimes++;
            if (waitedTimes >= timesToWait) 
                Console.WriteLine($" -- Element not found within (" +
                $"(timesToWait * 0.25) seconds). Canceling section...");
                return false;
            
            Thread.Sleep(250);
         while (!ExistsElement(element));

        Console.WriteLine($" -- Element found. Continuing...");
    //  Thread.Sleep(1000); // may apply here
        return true;
     catch  throw; 

之后你就可以玩timeout...

使By 成为您注意到页面中最后加载的内容(如javascript 元素和验证码),记住:它将在页面完全加载之前开始工作// rest of your application,因此放置Thread.Sleep(1000) 可能会很好最后只是为了确定......

还要注意,这个方法将在 Selenium 的 DRIVER.Navigate().GoToUrl(url); 的 60 秒标准超时之后调用

不是最好的,但是...正如我所说:一个好的 gambiarra 可以完成工作...

【讨论】:

【参考方案8】:

对于任何想要相反效果的人:设置超时时间超过 60 秒。

你需要同时使用:

new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), new FirefoxOptions(), TimeSpan.FromSeconds(120))

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(120);

new FirefoxDriver(binary, profile, timeSpan) 已过时。

【讨论】:

【参考方案9】:
driver.Manage().Timeouts().SetPageLoadTimeout(timespan) 

不工作。

这行得通。使用属性设置器语法。

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(15);

【讨论】:

以上是关于Selenium WebDriver - 如何使用 C# 设置页面加载超时的主要内容,如果未能解决你的问题,请参考以下文章

Selenium & webdriver.io 如何使用 executeScript?

如何使用selenium webdriver来判断一个网页加载完毕

如何使用 C# 在 Selenium WebDriver (Selenium 2) 中最大化浏览器窗口?

如何在 ruby​​ 中使用 Selenium WebDriver (selenium 2.0) 客户端设置选项

如何在 Java 中使用 Selenium WebDriver (Selenium 2) 输入文本框?

如何重新连接到 webdriver 使用 selenium 打开的浏览器?