Selenium WebDriver - 处理StaleElementReferenceException(Python)

时间:2015-12-15 03:38:11

标签: python selenium exception exception-handling

我正在使用Selenium编写Python代码,点击网页上的按钮。单击按钮后,按钮将更改为其他内容。我的代码完全正常,但Selenium误解了这是一个问题。我试图忽略这个例外并继续前进,但我尝试过的任何事情都没有效果。

from selenium.common.exceptions import StaleElementReferenceException

try:
    browser.find_element_by_xpath("//*[contains(text(), 'SomeButtonText')]").click()
except StaleElementReferenceException:
    pass

如何忽略异常并继续前进?我的代码适用于我尝试做的事情,但几秒后,就会抛出异常。

Message: Element not found in the cache - perhaps the page has changed since it was looked up

以下是来自Ubuntu终端的极其混乱的信息:

File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 107, in get_attribute
    resp = self._execute(Command.GET_ELEMENT_ATTRIBUTE, {'name': name})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 454, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 181, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: Element not found in the cache - perhaps the page has changed since it was looked up
Stacktrace:
    at fxdriver.cache.getElementAt (resource://fxdriver/modules/web-element-cache.js:9351)
    at Utils.getElementAt (file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command-processor.js:8978)
    at WebElement.getElementAttribute (file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command-processor.js:12019)
    at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command-processor.js:12534)
    at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command-processor.js:12539)
    at DelayedCommand.prototype.execute/< (file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command-processor.js:12481)

2 个答案:

答案 0 :(得分:1)

我找到了问题的答案。

这里的代码:

try:
    browser.find_element_by_xpath("//*[contains(text(), 'SomeButtonText')]").click()
except StaleElementReferenceException:
    pass

在for循环结束时执行。我完全错过了这个事实,它返回到循环的开头,我有一个单独的问题与Stale引用异常。

答案 1 :(得分:1)

这个问题是因为 Html正在加载,客户端仍在从服务器接收更新

我如何解决问题,你可以在点击之前简单地使用我的自定义等待。调用此函数

 public static void waitForElementPresent(final By by, int timeout,WebDriver driver)

在此之后,如果您使用浏览器,则使用chrome然后调用Scroll到该对象,这将解决您的问题代码

public static void waitForElementPresent(final By by, int timeout,WebDriver driver) { 

        waitForPageLoad(driver);
        WebDriverWait wait = (WebDriverWait)new WebDriverWait(driver,40).ignoring(StaleElementReferenceException.class); 
        /*  wait.until(new ExpectedCondition<Boolean>(){ 
            @Override 
            public Boolean apply(WebDriver webDriver) { 
              WebElement element = webDriver.findElement(by); 
              return element != null && element.isDisplayed(); 
            } 
          }); */
          try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           wait.until(ExpectedConditions.presenceOfElementLocated(by));
          wait.until(ExpectedConditions.elementToBeClickable(by));
          WebDriverWait wait2 = new WebDriverWait(driver, 40);
          wait2.until(ExpectedConditions.elementToBeClickable(by));

        }
    //wait for page to laod 
    public static void waitForPageLoad(WebDriver driver) {
        ExpectedCondition<Boolean> pageLoadCondition = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
                }
            };
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(pageLoadCondition);
    }