14

我正在使用如下所示的显式等待来检查元素是否可点击。

WebDriverWait(driver, 30).until(
        expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, "#search")))

但我得到错误

 <class 'selenium.common.exceptions.WebDriverException'>
Message: The command 'GET /session/.../displayed' was not found.

如果我使用time.sleep()它可以正常工作而不是 explicir 等待它可以正常工作。我已将 Safari 驱动程序初始化为

from selenium.webdriver import Safari
driver = Safari()

这是堆栈跟踪

  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/support/wait.py", line 71, in until
    value = method(self._driver)
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/support/expected_conditions.py", line 283, in __call__
    element = visibility_of_element_located(self.locator)(driver)
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/support/expected_conditions.py", line 127, in __call__
    return _element_if_visible(_find_element(driver, self.locator))
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/support/expected_conditions.py", line 147, in _element_if_visible
    return element if element.is_displayed() == visibility else False
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/remote/webelement.py", line 490, in is_displayed
    return self._execute(Command.IS_ELEMENT_DISPLAYED)['value']
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/remote/webelement.py", line 628, in _execute
    return self._parent.execute(command, params)
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/remote/webdriver.py", line 314, in execute
    self.error_handler.check_response(response)
  File "/Users/Library/Python/2.7/lib/python/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
WebDriverException: Message: The command 'GET /session/7.../displayed' was not found.
4

1 回答 1

5

此错误消息...

 <class 'selenium.common.exceptions.WebDriverException'>
Message: The command 'GET /session/.../displayed' was not found.

...意味着GET 请求失败/session/{session id}/element/{element id}/displayed


显示的元素

根据WebDriver W3C Editor's Draft元素显示算法是一个布尔状态,true表示元素已显示并且false表示元素未显示。要计算元素的状态,请调用Call(bot.dom.isShown, null, element). 如果这样做不会产生错误,则返回此函数调用的返回值。否则返回错误代码为 un​​known error的错误。

这个函数通常暴露给带有 URI 模板的 GET 请求

/session/{session id}/element/{element id}/displayed

分析

您已调用:

WebDriverWait(driver, 30).until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, "#search")))

element_to_be_clickable()类内部调用visibility_of_element_located()并定义为:

class element_to_be_clickable(object):
    """ An Expectation for checking an element is visible and enabled such that you can click it."""
    def __init__(self, locator):
    self.locator = locator

    def __call__(self, driver):
    element = visibility_of_element_located(self.locator)(driver)
    if element and element.is_enabled():
        return element
    else:
        return False

现在,visibility_of_element_located()类返回_element_if_visible(_find_element(driver, self.locator))定义为:

class visibility_of_element_located(object):
    """ An expectation for checking that an element is present on the DOM of a
    page and visible. Visibility means that the element is not only displayed
    but also has a height and width that is greater than 0.
    locator - used to find the element
    returns the WebElement once it is located and visible
    """
    def __init__(self, locator):
    self.locator = locator

    def __call__(self, driver):
    try:
        return _element_if_visible(_find_element(driver, self.locator))
    except StaleElementReferenceException:
        return False

同样,_element_if_visible()返回element if element.is_displayed() == visibility else False定义为:

def _element_if_visible(element, visibility=True):
    return element if element.is_displayed() == visibility else False

因此,由于失败if()的情况,因此您将错误视为对端点的请求失败。element.is_displayed() == visibility GET/session/{session id}/element/{element id}/displayed

如果没有相关的HTML前面的步骤,很难猜出确切的原因,但可能是以下任一原因:


原因

NoSuchElementException的原因可能是以下之一:

  • 您采用的定位器策略不会识别HTML DOM中的任何元素。
  • 您采用的定位器策略无法识别元素,因为它不在浏览器的Viewport中。
  • 您采用的定位器策略标识了元素,但由于属性style="display: none;"的存在是不可见的 .
  • 您采用的定位器策略不能唯一标识HTML DOM中的所需元素,并且当前会找到其他一些隐藏/不可见元素。
  • 您尝试定位的WebElement<iframe>位于标签内。

解决方案

解决NoSuchElementException的解决方案可以是以下之一:

  • 采用唯一标识所需WebElement的定位器策略。您可以借助开发工具(++或)并使用Element InspectorCtrlShiftIF12

    在这里,您将找到有关如何检查 selenium3.6 中的元素的详细讨论,因为 firebug 不再是 FF 56 的选项?

  • 使用execute_script()方法滚动元素以查看如下:

    elem = driver.find_element_by_xpath("element_xpath")
    driver.execute_script("arguments[0].scrollIntoView();", elem)
    

    在这里,您将找到有关使用 Selenium 在 Python 中滚动到页面顶部的详细讨论

  • Incase 元素具有属性style="display: none;" executeScript(),通过如下方法移除属性:

    elem = driver.find_element_by_xpath("element_xpath")
    driver.execute_script("arguments[0].removeAttribute('style')", elem)
    elem.send_keys("text_to_send")
    
  • 要检查元素是否在<iframe>遍历HTML中以通过以下任一方法定位相应的<iframe>标签和switchTo()所需的iframe :

    driver.switch_to.frame("iframe_name")
    driver.switch_to.frame("iframe_id")
    driver.switch_to.frame(1) // 1 represents frame index
    

    在这里您可以找到有关如何选择 html 元素的详细讨论,无论它在 selenium 中的哪个框架中?.

于 2018-08-03T16:30:17.057 回答