【问题标题】:Click on ember.js enabled element using Selenium单击使用 Selenium 启用 ember.js 的元素
【发布时间】:2020-12-05 18:53:49
【问题描述】:

我正在尝试使用selenium 在linkedin 页面上单击以下按钮:

<button id="ember607" class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view" data-control-name="share.post"><!---->
<span class="artdeco-button__text">
    
        Post
    
</span></button>

我试过用:

  • driver.find_element_by_id,但是按钮的id好像一直在变数
  • driver.find_element_by_xpath,但这包含按钮编号,所以也失败了
  • driver.find_element_by_class_name('share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view'),即使类名正确也会失败?

基本上,所有方法都会产生相同的错误信息:

Exception has occurred: NoSuchElementException
Message: no such element: Unable to locate element:{[*the_error_is_here*]}

我也试过xpath contains() 方法,但是这个找不到按钮。

请问点击此按钮的正确方法是什么?

我在windowsdriver = webdriver.Chrome 上使用python 版本3.9

【问题讨论】:

    标签: python selenium xpath ember.js css-selectors


    【解决方案1】:

    该元素是启用了Ember.js 的元素。因此,对于带有 Post 文本的元素上的 click(),您可以使用以下任一 Locator Strategies

    • 使用css_selector

      driver.find_element_by_css_selector("button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text").click()
      
    • 使用xpath

      driver.find_element_by_xpath("//button[contains(@class, 'share-actions__primary-action') and @data-control-name='share.post']/span[@class='artdeco-button__text' and contains(., 'Post')]").click()
      

    理想情况下,点击您需要为WebDriverWait 诱导element_to_be_clickable() 的元素,您可以使用以下Locator Strategies 之一:

    • 使用CSS_SELECTOR:

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text"))).click()
      
    • 使用XPATH

      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'share-actions__primary-action') and @data-control-name='share.post']/span[contains(., 'Post')]"))).click()
      
    • 注意:您必须添加以下导入:

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

    参考文献

    您可以在以下位置找到一些相关的详细讨论:

    【讨论】:

    • 这工作:WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'share-actions__primary-action') and @data-control-name='share.post']/span[contains(., 'Post')]"))).click() 与上述导入。谢谢
    • 不客气,如果您认为该问题对其他人有帮助,请点赞。
    【解决方案2】:

    有时按钮目前无法点击会出现问题。 试试这个:

    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    
    
    wait = WebDriverWait(driver, 10)
    
    button = wait.until(EC.element_to_be_clickable((By.XPATH, '[YOUR X_PATH TO THE BUTTON]')))
    driver.execute_script("arguments[0].click()", button)
    

    这不是用 selenium 点击任何按钮的最干净的方法,但对我来说,这种方法几乎每次都有效。

    【讨论】:

    • 我对此表示赞同,因为虽然答案不是公认的答案,但它有助于获得解决方案,它使用了类似的技术expected_conditionsWebDriverWaitBy
    【解决方案3】:
    //button[@class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view"]. 
    

    或者

    //button[contains(@id,'ember')]
    

    【讨论】:

    • 你的意思是像这样把它放到 xpath 中:driver.find_element_by_xpath('//button[@class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view"]')。如果是这样,这将返回相同的错误消息。
    • 无法使用//button[contains(@id,'ember')] 建议,因为ember+some_random_number很多 个按钮。
    • 尝试对第一个 xpath 使用显式等待,然后
    【解决方案4】:

    用 Post 找到 span 并点击它的按钮标签。

    //span[contains(text(), 'Post')]/parent::button
    

    【讨论】:

    • 我这样做了driver.find_element_by_xpath("//span[contains(text(), 'Post')]/parent::button").click(),但得到了这个错误Exception has occurred: NoSuchElementException Message: no such element: Unable to locate element: {"method":"xpath","selector":"//span[contains(text(), 'Post')]/parent::button"}
    【解决方案5】:

    通过 xpath 这应该可以工作:

    //button/span[contains(text(), "Post")]
    

    将它与等待元素结合起来:

    button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.XPATH, "//button/span[contains(text(), "Post")]"))
        )
    

    您的按类选择器的问题是多个类名。请参阅此问题:How to get elements with multiple classes,了解有关如何克服该问题的更多详细信息。

    【讨论】:

    • Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button/span[contains(text(), 'Post')]"}....
    • 如果你添加一个等待它会起作用吗(我已经编辑了答案)
    • 不,它给出了不同的错误:Exception has occurred: TypeError __init__() takes 2 positional arguments but 3 were given。注意:我将一组单引号更正为双引号。
    • 我有一个错字。为您更新。
    • 还是给Exception has occurred: TypeError __init__() takes 2 positional arguments but 3 were given
    猜你喜欢
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多