Selenium WebDriver-处理StaleElementReferenceException(Python)

Selenium WebDriver-处理StaleElementReferenceException(Python),python,selenium,exception,exception-handling,Python,Selenium,Exception,Exception Handling,我正在使用Selenium编写Python代码,它单击网页上的按钮。单击按钮后,按钮将更改为其他内容。我的代码工作得非常好,但Selenium将其误解为一个问题。我试图忽略这个异常,继续前进,但我尝试过的一切都不起作用 from selenium.common.exceptions import StaleElementReferenceException try: browser.find_element_by_xpath("//*[contains(text(), 'SomeBut

我正在使用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)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webelement.py”,第107行,在get_属性中
resp=self.\u execute(Command.GET\u ELEMENT\u属性,{'name':name})
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webelement.py”,第454行,在
返回self.\u parent.execute(命令,参数)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webdriver.py”,执行中的第201行
self.error\u handler.check\u响应(响应)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/errorhandler.py”,第181行,在check_响应中
引发异常类(消息、屏幕、堆栈跟踪)
selenium.common.exceptions.StaleElementReferenceException:Message:在缓存中找不到元素-可能页面在查找后已更改
堆栈跟踪:
在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)
在WebElement.getElementAttribute(file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command processor.js:12019)
在DelayedCommand.prototype.executeInternal\uh处(file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command processor.js:12534)
在DelayedCommand.prototype.executeInternal\u(file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command processor.js:12539)
在DelayedCommand.prototype.execute/<(file:///tmp/tmp24d8CK/extensions/fxdriver@googlecode.com/components/command processor.js:12481)

我找到了问题的答案

代码如下:

try:
    browser.find_element_by_xpath("//*[contains(text(), 'SomeButtonText')]").click()
except StaleElementReferenceException:
    pass
在for循环的末尾执行。我完全忽略了一个事实,即它返回到循环的开头,在那里我遇到了一个与过时引用异常有关的单独问题。

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

无论我如何为这个问题制定解决方案,您都可以使用我的自定义等待,然后单击。调用这个函数

 public static void waitForElementPresent(final By by, int timeout,WebDriver driver)
在此之后,如果您使用的是浏览器,而不是chrome,则调用滚动到该对象,这将修复您的问题代码

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);
    }
public static void waitForElementPresent(final By By,int timeout,WebDriver driver){
waitForPageLoad(驱动程序);
WebDriverWait wait=(WebDriverWait)新建WebDriverWait(驱动程序,40)。忽略(StaleElementReferenceException.class);
/*等待.until(新的ExpectedCondition(){
@凌驾
公共布尔应用(WebDriver WebDriver){
WebElement=webDriver.findElement(by);
返回元素!=null&&element.isDisplayed();
} 
}); */
试一试{
睡眠(1000);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
等待。直到(预期条件。元素的存在被定位);
等待.直到(预期条件.元素可选择(由));
WebDriverWait wait2=新的WebDriverWait(驱动程序,40);
等待2.直到(预期条件。元素可取消(由));
}
//等待页面刷新
公共静态void waitForPageLoad(WebDriver驱动程序){
ExpectedCondition pageLoadCondition=新建
期望条件(){
公共布尔应用(WebDriver驱动程序){
return((JavascriptExecutor)driver.executeScript(“return document.readyState”).equals(“complete”);
}
};
WebDriverWait wait=新的WebDriverWait(驱动程序,30);
等待.直到(pageLoadCondition);
}

您能否发布完整的回溯以及在哪一行引发错误?Thanks@alecxe谢谢你的回复。我在控制台上发布了这些信息,但我不知道这是否会有多大帮助。谢谢你的更新。但是,错误发生在代码的哪一行?@alecxe我在代码中发现了错误。非常简单的错误。我点击按钮的那一行是在一个循环的末尾。该行实际上执行正确,并返回到循环的顶部,在那里发生了另一个过时的引用问题。谢谢你的帮助!当然,请将其作为答案发布,并尽快接受,以解决该主题。谢谢分享。