selenium.common.exceptions.InvalidArgumentException:消息:无效参数:“使用”必须是使用等待和预期条件的字符串

Posted

技术标签:

【中文标题】selenium.common.exceptions.InvalidArgumentException:消息:无效参数:“使用”必须是使用等待和预期条件的字符串【英文标题】:selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'using' must be a string using waits and expected conditions 【发布时间】:2021-04-08 12:07:21 【问题描述】:

我正在使用 Python 3.7 和 Selenium 3.141.0。在加载缓慢的页面上,使用这样的代码来捕获 DOM 对象通常会有所帮助:

myDiv = WebDriverWait(driver, 60).until(
    expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass")))  

该代码在整个页面中搜索具有类myClass<div> 元素。但有时我想使用presence_of_element_located() 仅在给定的 WebElement 对象内进行搜索。例如,基于上面的代码,我想运行这样的代码:

myDiv2 = WebDriverWait(driver, 60).until(
    myDiv.presence_of_element_located((By.CSS_SELECTOR, "div.myClass2")))

第二个代码块不起作用;我收到一条错误消息,可以理解地告诉我,presence_of_element_located() 不是 WebElement 对象的方法。如果我用myDiv.find_element() 替换myDiv.presence_of_element_located(),代码也会失败。在这种情况下,我会收到一条无效参数消息:

selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'using' must be a string

有没有办法使用等待和预期条件来测试元素的存在,或者以其他方式搜索元素,同时将搜索限制为像 myDiv 这样的 WebElement 对象?从某种意义上说,这可以通过编写复杂的 CSS 或 Xpath 选择器来完成——但我想避免这种情况。

我查看了 SO 帖子和 Selenium documentation of expected conditions,但没有找到任何与此问题相关的内容。

【问题讨论】:

【参考方案1】:

Under the hood、presence_of_element_located 只使用find_element 并返回找到的元素。

考虑到这一点,您可以创建自己的自定义预期条件方法presence_of_element_located_inside_element(因为没有更好的名称):

from selenium.common.exceptions import NoSuchElementException


class presence_of_element_located_inside_element(object):
    def __init__(self, first_locator, second_locator):
        self.first_locator = first_locator
        self.second_locator = second_locator

    def __call__(self, driver):
        try:
            first_elem = driver.find_element_by_css_selector(self.first_locator)
            second_elem = first_elem.find_element_by_css_selector(self.second_locator)
            return second_elem
        except NoSuchElementException:
            return False

然后你可以在你的测试中使用它:

elem = WebDriverWait(driver, 20).until(presence_of_element_located_inside_element('div.myClass1', 'div.myClass2'))

这仅用于说明目的,仅支持字符串 CSS 选择器。

当然,它可以调整为将By 类型作为参数,然后您可以为每个元素使用不同的定位器策略。

【讨论】:

【参考方案2】:

presence_of_element_located()

presence_of_element_located() 是检查页面 DOM 上是否存在元素的期望。这并不一定意味着该元素是可见的,并且用于查找该元素一旦找到就返回WebElement。

一旦通过以下方式返回元素myDiv

myDiv = WebDriverWait(driver, 60).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass")))

要针对找到的 WebElement 搜索另一个元素,您可以使用以下解决方案:

myDiv2 = WebDriverWait(myDiv, 60).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "div.myClass2")))

【讨论】:

以上是关于selenium.common.exceptions.InvalidArgumentException:消息:无效参数:“使用”必须是使用等待和预期条件的字符串的主要内容,如果未能解决你的问题,请参考以下文章