web-dev-qa-db-fra.com

Sélénium Élément non visible exception

On m'a demandé d'écrire à un analyseur pour qu'il clique sur un bouton d'un site Web et je ne parviens pas à cliquer sur l'un des boutons. Le code suivant fonctionne sur tous les boutons sauf un. 

Voici le code HTML: http://Pastebin.com/6dLF5ru8

voici le code source HTML: http://Pastebin.com/XhsedGLb

code python:

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

Je reçois cette erreur.

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

selon Saifur, je viens d'essayer d'attendre avec le même élément exception non visible:

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

Si vous regardez la source de la page, vous comprendrez que presque tous les éléments SELECT, DIV sont faked et créés à partir de JavaScript, c'est pourquoi Webdriver ne peut pasNIleur.

Il existe cependant une solution de contournement, en utilisant ActionChains pour ouvrir votre console de développeur et injecter un artificial CLICK sur l'élément souhaité, qui est en fait le Label qui déclenche leNBAdata loading ... voici un exemple de travail:

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

Alternativement, pour remplacer toutes les commandes ActionChains, vous pouvez simplement exécuter execute_script comme ceci:

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

Voilà, au moins sur mon dossier local de toute façon ... J'espère que ça aide!

enter image description here

40
Anzel

Ce qui a fonctionné pour moi a été de trouver l'élément juste avant l'élément problématique (c'est-à-dire juste en termes d'ordre de tabulation), puis d'appeler Tab sur cet élément.

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

Après cela, j'ai pu envoyer des actions à l'élément.

15
twasbrillig

La solution actuelle de ce fil n'a pas fonctionné pour moi.

cependant,

celui-ci a:

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

l'astuce consiste à utiliser: 

EC.visibility_of_element_located

le WebDriverWait 

WebDriverWait

à partir de cette importation: 

depuis Selenium.webdriver.support

depuis Selenium.webdriver.support.ui importer WebDriverWait

3
Tom

Je vous suggère d'utiliser xpath avec explicit wait

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

si "L'élément n'est pas visible", alors rendez-leVISIBLE

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")
1
Andrei.Danciuc

J'ai fini par utiliser la solution de @ twasbrillig, mais au lieu de rechercher l'élément précédent et d'envoyer une touche TAB, je recherche l'élément souhaité, envoie une touche TAB avec cet élément, puis une touche MAJ + TAB au conducteur:

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)
0
bbobbo

J'ai essayé d'utiliser les autres méthodes, mais à la fin, j'ai trouvé que le moyen le plus simple consistait simplement à cliquer sur le bouton et à détecter l'erreur. Cela me permet d’effectuer d’autres actions selon que cela fonctionne (True) ou non (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)
0
Guest

Au lieu de get_element_by_id(), vous pouvez essayer elem = browser.find_element_by_css_selector('#elemId') (allez à la page Web et à l’élément, faites un clic droit dessus et Copy CSS Selector, ou quelque chose du genre.) C’est ce que j’ai fait et cela fonctionne. Vous essayez également 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. Quelque chose fonctionnera. Après la id, le CSS Selector est votre meilleur choix.

0
Nik-Lz