Python 硒元素不可见异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27927964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:28:29  来源:igfitidea点击:

Selenium Element not visible exception

pythonselenium

提问by user4450305

I have been tasked with writing a parser to click a button on a website and I am having issues to click only one of the buttons. The following code works on every button except one.

我的任务是编写一个解析器来单击网站上的按钮,但我无法仅单击其中一个按钮。以下代码适用于除一个按钮之外的每个按钮。

Here's the html: http://pastebin.com/6dLF5ru8

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

here's the source html: http://pastebin.com/XhsedGLb

这是源 html:http: //pastebin.com/XhsedGLb

python code:

蟒蛇代码:

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

I am getting this error.

我收到此错误。

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

as per Saifur I just tried waits with the same element not visible exception:

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

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

采纳答案by Anzel

If you look at the page source, you'll understand that almost all of theSELECT, DIVelements are fakedand created from JavaScript, that is why webdriver cannot SEEthem.

如果你看一下页面的源代码,你会明白,几乎所有的SELECTDIV都是元素faked和从JavaScript创建的,这就是为什么webdriver的不能查阅它们。

There's a workaround though, by using ActionChainsto open your developer console, and inject an artificialCLICK on the desired element, which in fact, is the Labeltriggering the NBAdata loading... here's a working example:

不过,有一个解决方法,通过使用ActionChains打开您的开发者控制台,并在所需元素上注入一个人工CLICK,这实际上是触发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()

Alternatively to replace all the ActionChainscommands, you can simply run execute_scriptlike this:

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

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

There you go, at least on my local file anyway... Hope this helps!

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

enter image description here

在此处输入图片说明

回答by Saifur

I suggest you use xpathwith explicitwait

我建议你使用xpathexplicit等待

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

回答by twasbrillig

What worked for me was to find the element just before the problematic one (that is, just before it in terms of tab order), then call Tab on that element.

对我有用的是在有问题的元素之前找到元素(也就是说,就 Tab 顺序而言,就在它之前),然后在该元素上调用 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

After doing that, I was able to send actions to the element.

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

回答by Andrei.Danciuc

if "Element is not currently visible" then make it VISIBLE

如果“元素当前不可见”,然后使之可见

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")

回答by Nikos

Instead of get_element_by_id()you can try elem = browser.find_element_by_css_selector('#elemId')(go to that webpage and the element, right click it and Copy CSS Selector, or something like that.) This is what i did and it works. You also try 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)etc. Something will work. After the idthe CSS Selectoris your best bet.

而不是get_element_by_id()您可以尝试elem = browser.find_element_by_css_selector('#elemId')(转到该网页和元素,右键单击它和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)等东西会工作。之后,idCSS Selector是你最好的选择。

回答by Tom

The actual solution of this thread did not work for me.

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

however,

然而,

this one did :

这个做了:

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

the trick is to use :

诀窍是使用:

EC.visibility_of_element_located

EC.visibility_of_element_located

the WebDriverWait

WebDriverWait

WebDriverWait

网络驱动程序等待

from this import :

从这个进口:

from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.support.ui import WebDriverWait

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

从 selenium.webdriver.support.ui 导入 WebDriverWait

回答by bbobbo

I ended up using @twasbrillig's solution, but instead of finding the previous element and sending a TAB keypress, I find the desired element, send a TAB keypress with that element, and then a SHIFT + TAB keypress to the driver:

我最终使用了@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)

回答by Guest

I tried using the other methods but in the end found that the simplest way was to just try and click the button, and catch the error. This allows me to perform other actions based on if it worked (True) or didn't (False).

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

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)

回答by CONvid19

The way I solved this in pythonwas:

我解决这个问题的方法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)