如果我们使用 find_element 而不是 find_element_by,则会出现错误“传入的定位器值无效”

ask*_*ern 6 python selenium-webdriver

我正在使用 Python-Webdriver 来自动执行“单击”操作。这是我的代码:

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.common.exceptions import InvalidSelectorException


LOGIN_BUTTON = (By.XPATH, '//a[contains(@class,"aui-nav-link login-link")]')
NEWS_OPTION = (By.ID, 'blq-nav-news')

driver = webdriver.Chrome()
driver.implicitly_wait(30)
driver.get("http://bbc.co.uk/")
myDynamicElement = driver.find_element(NEWS_OPTION)
myDynamicElement.click()
Run Code Online (Sandbox Code Playgroud)

控制台产生异常如下

    raise InvalidSelectorException("Invalid locator values passed in")
selenium.common.exceptions.InvalidSelectorException: Message: Invalid locator values passed in
Run Code Online (Sandbox Code Playgroud)

但是,如果我改变线路

“myDynamicElement = driver.find_element(NEWS_OPTION)”

“myDynamicElement = driver.find_element_by_id('blq-nav-news')”

,没有例外,脚本按预期工作。

我发现根本原因是我们不使用

查找元素依据_*

。所以我想知道这是对 Python-Webdriver 的限制吗?我们是否有解决方案来解决我的问题,而无需像我一样更改我的代码。

ale*_*cxe 8

根据文档,您可以直接使用find_element_by_*快捷方式或“私有”方法find_element()find_elements()

除了上面给出的公共方法之外,还有两个私有方法可能对页面对象中的定位器有用。这是两个私有方法:find_element 和 find_elements。

用法示例:

from selenium.webdriver.common.by import By

driver.find_element(By.XPATH, '//button[text()="Some text"]')
driver.find_elements(By.XPATH, '//button')
Run Code Online (Sandbox Code Playgroud)

但是,在您的情况下,find_element()您传递的是一个参数 - a ,而不是传递2 个参数tuple NEWS_OPTION。您只需将元组解压缩为位置参数:

NEWS_OPTION = (By.ID, 'blq-nav-news')
myDynamicElement = driver.find_element(*NEWS_OPTION)
Run Code Online (Sandbox Code Playgroud)

或者,作为替代方案,您也可以使用关键字参数:

NEWS_OPTION = {'by': By.ID, 'value': 'blq-nav-news'}
myDynamicElement = driver.find_element(**NEWS_OPTION)
Run Code Online (Sandbox Code Playgroud)

而且,每当您对事情应该如何工作有任何疑问时,只需挖掘源代码并亲自澄清即可。在这种情况下,看看find_element_by_id()方法是如何实际实现的

def find_element_by_id(self, id_):
    """Finds an element by id.

    :Args:
     - id\_ - The id of the element to be found.

    :Usage:
        driver.find_element_by_id('foo')
    """
    return self.find_element(by=By.ID, value=id_)
Run Code Online (Sandbox Code Playgroud)