【问题标题】:Locating elements through "begins with" method of CssSelector using selenium and python使用 selenium 和 python 通过 CssSelector 的“开始于”方法定位元素
【发布时间】:2018-12-29 03:54:50
【问题描述】:

我正在使用 selenium 来定位和选择一个使用 find_element_by_id 的 HTML 元素。直到昨天,当 Web 开发人员将元素的 ID 更改为动态字符串时,我对此没有任何问题。

下面是 ID 的示例:input_205

之前,我使用browser.find_elements_by_xpath('//*[@id="input_205"]').send_keys(viewId) 来定位元素并且效果很好,但是现在该字符串中的数值会动态变化。

我发现的唯一模式是每次加载页面时它都是一个三位数字。

我想知道是否有一种方法可以将我的 xpath 设置为某种“开头”或“包含”,这样无论input_ 之后的三位数字如何,我仍然可以定位 ID。提前谢谢!

【问题讨论】:

    标签: python selenium selenium-webdriver xpath css-selectors


    【解决方案1】:

    正如您在问题中提到的,您直到昨天都没有问题通过以下方式定位元素:

    browser.find_elements_by_xpath('//*[@id="input_205"]').send_keys(viewId)
    

    那是因为所需的元素被分配了一个静态的id

    但现在元素 id 是动态的,并通过一些 JavaScript/AjaxCalls 进行分配。因此,要识别元素,您必须构造一个动态的Locator Strategy。但是您的代码试验只给了我们关于 id 属性的想法。要构建动态定位器,您可以使用以下提到的项目中的多个项目:

    • <tagName> 标签例如<input>
    • class 属性,例如class="input-full"
    • 部分id 属性,例如input_ 来自id="input_205"
    • 角度属性,例如ng-click="navigate('export',$event)"

    最重要的是,由于该元素是调用send_keys() 的动态元素,因此您必须将WebDriverWait 与设置为element_to_be_clickable(locator)expected_conditions 方法结合使用。

    例如,如果元素在HTML DOM中表示如下:

    <div class="form-group clearfix">
            <input id="input_205" class="input-full" type="text" ng-click="navigate('run',$event)">
    </div>
    

    您的有效定位器将是:

    • CSS_SELECTOR:

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.input-full[id^='input_']"))).send_keys(viewId)
      
    • XPATH:

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='input-full' and starts-with(@id, 'input_')]"))).send_keys(viewId)
      

    注意 A:与 cssSelectors 一起使用的通配符的参考:

    • ^ :表示一个属性值开头
    • * : 表示一个属性值包含
    • $:表示一个属性值结尾

    注意 B:您必须添加以下导入:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

    【讨论】:

      【解决方案2】:

      试试下面的 XPath:

      //*[starts-with(@id, 'input_')]
      

      【讨论】:

      • 当我测试它时,终端抛出“SyntaxError: invalid syntax” 这是我写的:browser.find_element_by_xpath('//*[starts-with(@id, 'input_')]')我使用正确吗?
      • @JessicaFeliciano ,这是因为引号使用不一致。试试browser.find_element_by_xpath("//*[starts-with(@id, 'input_')]")
      • 更新:我已经像这样修改了我的代码 - browser.find_element_by_xpath("//*[starts-with(@id, 'input_')]") 当我进行此修改时,我收到以下错误:“消息:元素不可见”
      • @dangi13 ,仅供参考 ElementNotVisibleException 如果元素位于 iframe 内,则不会引发 NoSuchElementException
      • @JessicaFeliciano ,正如已经建议的那样,尝试将 ExplicitWait 应用为 WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[id^='input_']"))).send_keys("foo")。如果它不起作用,请检查您的选择器是否只有一个元素匹配:print(len(browser.find_elements_by_css_selector("[id^='input_']")))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 2019-10-13
      • 2019-09-01
      • 1970-01-01
      • 2014-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多