【问题标题】:Selenium Element not visible exception硒元素不可见异常
【发布时间】:2015-03-11 18:03:44
【问题描述】:

我的任务是编写一个解析器来单击网站上的一个按钮,但我在只单击一个按钮时遇到了问题。以下代码适用于除一个之外的每个按钮。

这里是html: http://pastebin.com/6dLF5ru8

这里是源代码: http://pastebin.com/XhsedGLb

python 代码:

 driver = webdriver.Firefox()  
 ...
 el = driver.find_element_by_id("-spel-nba")
 actions.move_to_element(el)
 actions.sleep(.1)
 actions.click()
 actions.perform()

我收到此错误。

ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with

根据 Saifur,我刚刚尝试使用相同元素等待不可见异常:

wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.XPATH, "//input[contains(@id,'spsel')][@value='nba']"))).click()

【问题讨论】:

  • 谢谢,我刚试过等待,但它超时了
  • 您提供的 html 中没有匹配的类名。您使用了错误的选择器
  • Saifur,我只是尝试编辑。它回到了我第一次发布时的位置。
  • 像这样:driver.find_element_by_xpath("//input[contains(@id,'spsel')][@value='nba']")

标签: python selenium


【解决方案1】:

我在python 中解决这个问题的方法是:

try:
    # the element you want to scroll to
    element = driver.find_element_by_id("some_id") 
    ActionChains(driver).move_to_element(element).perform()
    element.send_keys(Keys.TAB).key_up(Keys.SHIFT)
    #element.click()
except Exception as e:
    print(e)

【讨论】:

    【解决方案2】:

    我尝试使用其他方法,但最后发现最简单的方法是尝试单击按钮,然后捕获错误。这使我可以根据它是否有效(真)或无效(假)来执行其他操作。

    def click_button(html_object):
     try:
      html_object.click()
     except:
      return False #most likely because it is NotVisible object and can be ignored
     return True
    
    ...
    ...
    click_button(actions)
    

    【讨论】:

      【解决方案3】:

      我最终使用了@twasbrillig 的解决方案,但我没有找到前一个元素并发送 TAB 按键,而是找到了所需的元素,发送带有该元素的 TAB 按键,然后向驱动程序发送 SHIFT + TAB 按键:

      from selenium import webdriver
      from selenium.webdriver.common.keys import Keys
      
      driver = webdriver.Firefox()  
      el = driver.find_element_by_id("-spel-nba")
      el.send_keys(Keys.TAB)
      webdriver.ActionChains(driver).key_down(Keys.SHIFT).send_keys(Keys.TAB).key_up(Keys.SHIFT)
      

      【讨论】:

        【解决方案4】:

        这个线程的实际解决方案对我不起作用。

        然而,

        这个做到了:

        element  = WebDriverWait(driver, 3).until(EC.visibility_of_element_located((By.XPATH, xpaths['your_xpath_path'])))
        

        诀窍是使用:

        EC.visibility_of_element_located

        WebDriverWait

        WebDriverWait

        从此导入:

        从 selenium.webdriver.support 导入 expected_conditions 作为 EC

        从 selenium.webdriver.support.ui 导入 WebDriverWait

        【讨论】:

          【解决方案5】:

          您可以尝试elem = browser.find_element_by_css_selector('#elemId') 而不是get_element_by_id()(转到该网页和元素,右键单击它和Copy CSS Selector,或类似的东西。)这就是我所做的并且它有效。您还可以尝试find_element_by_link_text(text)find_element_by_partial_link_text(text)find_element_by_tag_name(tagName_case_insensitive_here)find_element_by_name(name) 等。有些东西会起作用。在id 之后,CSS Selector 是您最好的选择。

          【讨论】:

            【解决方案6】:

            如果“元素当前不可见”,则使其可见

            f.e.

            >>> before is hidden top is outside of page
            <input type="file" style="position: absolute;top:-999999" name="file_u">
            
            
            >>> after move top on in page area
            DRIVER.execute_script("document.getElementByName('file_u').style.top = 0;")
            time.sleep(1); # give some time to render
            DRIVER.find_element_by_name("file_u").send_keys("/tmp/img.png")
            

            【讨论】:

              【解决方案7】:

              对我有用的是找到问题元素之前的元素(也就是说,就标签顺序而言,就在它之前),然后在该元素上调用 Tab。

              from selenium.webdriver.common.keys import Keys
              elem = br.find_element_by_name("username")
              elem.send_keys(Keys.TAB) # tab over to not-visible element
              

              这样做之后,我能够向元素发送操作。

              【讨论】:

                【解决方案8】:

                如果您查看页面源代码,您会明白几乎所有的SELECTDIV 元素都是faked 并且是由 JavaScript 创建的,这就是为什么 webdriver 无法SEE他们。

                不过有一个解决方法,通过使用ActionChains 打开您的开发者控制台,并在所需元素上注入 artificial CLICK,实际上就是 Label触发 NBA 数据加载...这是一个工作示例:

                from selenium import webdriver
                from selenium.webdriver.common import action_chains, keys
                import time
                
                driver = webdriver.Firefox()
                driver.get('Your URL here...')
                assert 'NBA' in driver.page_source
                action = action_chains.ActionChains(driver)
                
                # open up the developer console, mine on MAC, yours may be diff key combo
                action.send_keys(keys.Keys.COMMAND+keys.Keys.ALT+'i')
                action.perform()
                time.sleep(3)
                # this below ENTER is to rid of the above "i"
                action.send_keys(keys.Keys.ENTER)
                # inject the JavaScript...
                action.send_keys("document.querySelectorAll('label.boxed')[1].click()"+keys.Keys.ENTER)
                action.perform()
                

                或者替换所有ActionChains 命令,您可以像这样简单地运行execute_script

                driver.execute_script("document.querySelectorAll('label.boxed')[1].click()")
                

                你去吧,至少在我的本地文件上......希望这会有所帮助!

                【讨论】:

                • @user4450305,没问题,我很乐意提供帮助;)这实际上是一个非常棘手的问题,我在浏览器检查器上尝试了 10 分钟......在我查看页面之前来源并弄清楚发生了什么。为您的问题 +1。
                • @Anzel action 是否支持多浏览器?而且,你能解释一下javascript部分吗?只是为了我的理解
                • @Saifur,是的,动作是多浏览器兼容的,我通常用它来查看代码和浏览器之间的所有交互动作,就像你看到自己直接执行的一连串动作。 execute_script 只是直接执行 javascript 的一种更直接的方式。关于 JavaScript,因为站点中的数据基本上是由 javascript 操作的,并且动态地提供数据并构建 DOM。例如,如果将它们设置为不可见或禁用,webdriver 将看不到它们。在这种情况下,您需要注入脚本以实现期望操作
                • 我可能有类似的问题:ElementNotVisibleException: 错误。你知道在 Robot Framework 中有什么方法吗?
                • @Anna - 我以前没有使用过 Robot 框架,但请注意 selenium 是集成的。所以理论上任何适用于 selenium 的东西也应该适用于你的 Robot 框架。让我知道你过得怎么样。
                【解决方案9】:

                我建议你使用 xpathexplicit 等待

                //input[contains(@id,'spsel')][@value='nba']
                

                【讨论】:

                • 同样的错误:ElementNotVisibleException:消息:元素当前不可见,因此可能无法与之交互
                • @Saifur,正常情况下它应该可以工作,但是这种情况下如果你检查页面源,几乎所有的元素都是由 JavaScript 伪造/动态创建的,webdriver 看不到它们
                猜你喜欢
                • 2019-01-05
                • 1970-01-01
                • 2016-07-08
                • 1970-01-01
                • 2018-05-18
                • 1970-01-01
                • 1970-01-01
                • 2015-05-03
                • 1970-01-01
                相关资源
                最近更新 更多