关于python:同一个命令在执行时有效,但在第二次执行时抛出异常?

Same command works once when executed but throws an exception when executed a second time?

所以我是一个非常新的人,我正在尝试找出一些可以在Python中使用的东西。

元素:

1
 Show More Results

xpath://*[@id="scroll2"]

我使用shell执行:

1
2
3
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), ' Show More Results')]")))
element.click()

执行上述操作后,元素:

1
 Show More Results

xpath://*[@id="scroll3"]

当我再次执行相同的命令时,它抛出一个异常:

1
2
3
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), ' Show More Results')]")))
element.click()

例外

Traceback (most recent call last):
File"", line 1, in
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), ' Show More Results')]")))
File"C:\Python34\lib\site-packages\selenium\webdriver\support\wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:

无法理解原因。或者一种方法。


我坚信这与您正在测试的应用程序的构建方式有关:似乎单击Scroll2按钮会使其不可见,并将Scroll3按钮添加到页面中。

之后,当您调用wait.until(…)时,WebDriver会找到Scroll2按钮(因为只检查内部文本的xpath表达式仍然与之匹配),然后等待它获得可单击性,因为它不再可见,所以它永远不会找到。

您可以使用如下简单网页重新创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
    <head>    
       
            document.onreadystatechange = function() {
                var element = document.getElementById("1");

                element.addEventListener("click", function() {
                    this.style.display ="none";

                    document.getElementById("2").style ="";
                });
            }
       
    </head>
    <body>
        Show More Results
        Show More Results
    </body>
</html>

这个python片段:

1
2
3
4
5
6
7
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), 'Show More Results')]")))
element.click()

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), 'Show More Results')]")))
element.click()

这里还有第二个等待,直到(…)会超时,即使页面看起来是正确的。

基本上有两种解决方案:

  • 更改HTML,这样一旦添加了Scroll3按钮,Scroll2按钮实际上就从DOM中删除,或者
  • 更改测试,使其能够以更稳定的方式找到要单击的按钮。例如,对于上面提到的示例,您可以将显示样式添加到xpath定位器,以确保只找到显示的元素。

例子:

1
2
3
4
5
6
7
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), 'Show More Results') and not(contains(@style, 'display: none'))]")))
element.click()

wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH,"//*[contains(text(), 'Show More Results') and not(contains(@style, 'display: none'))]")))
element.click()

请注意,您可能还必须在定位器中包含祖先可见性,有关详细信息,请参阅以下问题:如何使用xpath仅选择可见元素?