3
votes

selenium.common.exceptions.ElementNotVisibleException: Message: élément non interactif et attente explicite ne fonctionne pas avec Selenium et Python

J'essaie d'accéder à PenFed afin d'obtenir mon montant impayé actuel. J'ai fait pas mal de recherches et malheureusement, je reste perplexe. J'utilise Python Selenium et j'essaie de cliquer sur le bouton de connexion initial sur le côté pour voir le champ du nom d'utilisateur. Voici le code HTML de l'élément:

element = driver.find_element_by_id("mobile-login")
driver.execute_script("$(arguments[0]).click();", element)

Lorsque j'essaye d'exécuter le code suivant:

raise TimeoutException(message, screen, stacktrace) selenium.common.exceptions.TimeoutException: Message:

J'obtiens l'erreur suivante:

try:
    WebDriverWait(driver, 5).until(EC.visibility_of_element_located((By.ID, "mobile-login"))).click()
except ElementNotVisibleException:
    WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.ID, "mobile-login"))).click()

Même lorsque j'essaie d'utiliser des fonctions WebDriver Wait comme celles-ci:

selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable

Peu importe combien de temps je les fais attendre, je reçois un message de délai d'expiration:

XXX

Toutes mes recherches indiquent que l'invocation d'une fonction d'attente devrait résoudre ce problème, mais cela ne fonctionne pas pour moi. J'ai également lu qu'il pourrait y avoir une superposition d'image au-dessus de l'élément que je devrais invoquer avant de cliquer sur le bouton, mais je n'ai rien vu dans le code du site Web. Si je le teste, le seul moyen de cliquer sur le bouton via le code est de cliquer physiquement dessus en premier, donc je ne suis pas au courant de tout ce que je peux utiliser. Merci d'avance pour l'aide!

MISE À JOUR: J'ai découvert que le code suivant fonctionne pour moi:

driver.find_element_by_id("mobile-login").click()

Mais je ne sais pas ce que execute_script le fait réellement. Quelqu'un peut-il expliquer que ce morceau de code fonctionne ou si d'autres alternatives fonctionnent pour eux?


2 commentaires

Je suis un peu confus, essayez-vous d'interagir avec cet élément?


@Rajagopalan Oui, quelqu'un d'autre dans ce fil a souligné qu'en ajustant mon navigateur, je pourrais voir l'ID du bouton de connexion réel, mais je ne voyais que l'ID pour la connexion mobile. Merci!


3 Réponses :


1
votes

Le code que vous avez spécifié est JQuery . execute_script (p1, p2) exécute un script js, où p1 est le script (dans votre cas, une ligne JQuery qui clique sur l'élément) et p2 est l'élément souhaité. Il semble que vous ne devriez pas avoir besoin de p2 si arguments [0] est égal à "element", mais je ne suis pas totalement sûr.

Une solution potentielle consiste à utiliser un compteur pour le nombre de fois où vous avez cliqué sur l'élément. Si le compteur atteint un certain nombre et que la page ne change pas (vous pouvez vérifier en trouvant un élément / une valeur unique sur votre page actuelle), vous savez qu'il n'est pas cliquable.

Bonne chance!


1 commentaires

Je vous remercie! Je pense que c'était plus une note annexe, je ne pense pas que le execute_script attaquait la racine du problème, juste la branche. Je l'ai trouvé sur stackoverflow et cela a fonctionné, mais cela me donne un bon aperçu de la fonction!



0
votes

L'élément souhaité est un élément dynamique donc pour localiser l'élément vous devez induire WebDriverWait pour que l'élément soit cliquable et vous pouvez utiliser la solution suivante:

  • Bloc de code:

    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
    options = Options()
    options.add_argument('start-maximized')
    options.add_argument('--disable-extensions')
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get('https://www.penfed.org/')
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.pfui-button.login-slide-button.pfui-button-login.dtm-global-nav[data-id='Open Log In Drawer']"))).click()
    
  • Instantané du navigateur:

 penfed.org


1 commentaires

J'utilisais la fonction d'attente du pilote Web, mais je rencontrais toujours des problèmes. Je pense que l'essentiel était que je recherchais le mauvais ID de bouton, donc je rencontrais des exceptions de délai d'expiration à chaque fois que j'exécutais un pilote Web.



0
votes

Le lien sur lequel vous essayez de cliquer concerne le site mobile et n'est pas visible si vous consultez le site avec des résolutions de bureau. Si vous réduisez votre navigateur jusqu'à ce qu'il change de disposition, vous verrez apparaître le bouton LOGIN correspondant à ce lien. C'est pourquoi vous obtenez l ' ElementNotVisibleException .

Pour votre deuxième question, la raison pour laquelle l'utilisation de .execute_script () fonctionne est qu'elle exécute JS directement et peut cliquer sur n'importe quoi ... caché ou pas. Selenium a été conçu pour interagir avec la page comme le ferait un utilisateur afin de ne pas vous laisser cliquer sur des éléments invisibles, etc. Si vous prévoyez que votre script agisse comme un utilisateur, vous voudrez éviter d'utiliser .execute_script () car il vous permet de faire des choses sur la page qu'un utilisateur ne peut pas faire.

Si vous souhaitez vous connecter comme le ferait un utilisateur de bureau, vous devez cliquer sur le bouton "SE CONNECTER" en utilisant le sélecteur CSS ci-dessous

button[data-id='Open Log In Drawer']

Cela ouvrira un côté panneau où vous pouvez entrer votre nom d'utilisateur, etc. et vous connecter. Pour info ... vous aurez probablement besoin d'attendre pour donner au panneau une chance de s'ouvrir avant de continuer le processus de connexion.


0 commentaires