selenium.common.exceptions.ElementNotInteractableException:消息:使用Selenium Python单击元素时元素不可交互

时间:2019-03-19 07:09:31

标签: python-3.x selenium selenium-webdriver webdriver webdriverwait

我知道有人问过这个问题,但是我需要针对此错误的一些解决方案:

 Traceback (most recent call last):
 File "goeventz_automation.py", line 405, in <module>
if login(driver) is not None:
File "goeventz_automation.py", line 149, in login
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/support/wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:

这是发生错误的代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import TimeoutException
import urllib.request as request
import urllib.error as error
from PIL import Image
from selenium.webdriver.chrome.options import Options
import datetime as dt
import time
from common_file import *
from login_credentials import *

def login(driver):
global _email, _password
if waiter(driver, "//a[@track-element='header-login']") is not None:
    #login = driver.find_element_by_xpath("//a[@track-element='header-login']")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()
    #login.click()
    if waiter(driver,"//input[@id='user_email']") is not None:
        email = driver.find_element_by_xpath("//input[@id='user_email']")
        password = driver.find_element_by_xpath("//input[@id='password']")
        email.send_keys(_email)
        password.send_keys(_password)
        driver.find_element_by_xpath("//button[@track-element='click-for-login']").click()
        return driver
    else:
        print("There was an error in selecting the email input field. It may be the page has not loaded properly.")
        return None
else:
    print("There was an error in selecting the header-login attribute on the page.")
    return None

if __name__ == '__main__':
    chrome_options = Options()
    chrome_options.add_argument('--headless')
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument('--disable-dev-shm-usage')

    driver = webdriver.Chrome('/usr/bin/chromium/chromedriver',chrome_options=chrome_options)
    #d.get('https://www.google.nl/')
    #driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get('https://www.goeventz.com/')
    if login(driver) is not None:
        print(create_event(driver))

我认为Keys.ENTER存在一些问题,但我不知道如何解决。我已经尝试了所有可能的解决方案..........

5 个答案:

答案 0 :(得分:3)

复制完整的 xpath 而不是仅复制 xpath。它会起作用

答案 1 :(得分:1)

您应该使用硒login.send_keys(Keys.ENTER)代替您使用的硒click()方法,而不是WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()

您可以先检查元素是否可单击,然后再单击它。 喜欢:

body.addEventListener('keyup', (ev) => this.moveAvatar(ev));

答案 2 :(得分:1)

此错误消息...

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

...表示当您尝试在其上调用click()时,所需的元素不是可交互的

一些事实:

  • 初始化 Chrome 浏览器时,始终以最大化模式进行操作。
  • 您可以禁用扩展名
  • 您还需要 disable-infobars

我使用了与您构建的相同的 xpath ,并且可以使用以下解决方案:

  • 代码块:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    options = webdriver.ChromeOptions()
    options.add_argument("start-maximized");
    options.add_argument("disable-infobars")
    options.add_argument("--disable-extensions")
    driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get("https://www.goeventz.com/")
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()
    
  • 浏览器快照:

login_page

答案 3 :(得分:1)

概述

您似乎在XPATH上遇到问题,无法找到“提交”按钮,或者您的提交按钮不可点击,或者您的“提交”按钮上附加了一些客户端事件(javascript / etc),因此有效地提交页面。

在大多数情况下,调用pw.submit()方法应该摆脱等待提交按钮变为可单击状态的需要,并且在大多数情况下避免了查找按钮时出现任何问题。在许多其他网站上,某些必要的后端过程由实际上单击“提交”按钮后执行的客户端活动准备(尽管在旁注中,这不是最佳做法,因为它会使网站不易访问,等等,我离题了)。首先,重要的是要观察脚本的执行情况,并确保您没有在网页上看到任何有关所提交凭据的明显错误。

但是,某些网站还要求您在输入用户名,密码和提交页面之间添加一定的最短时间,以使该页面被视为有效的提交过程。我什至已经进入要求您一次使用send_keys 1来输入用户名和密码的网站,以避免使用某些反抓取技术。在这些情况下,我通常在调用之间使用以下命令:

from random import random, randint

def sleepyTime(first=5, second=10):
    # returns the value of the time slept (as float)
    # sleeps a random amount of time between the number variable in first
    # and the number variable second (in seconds)
    sleepy_time = round(random() * randint(first, second), 2)
    sleepy_time = sleepy_time if sleepy_time > first else (first + random())
    sleep(sleepy_time)
    return sleepy_time

除非您在登录函数中的某处更改了_email和_password变量,并且您希望将该更改沉淀到其他作用域中,否则我看不出有什么用来使_email和_password变量具有全局性。

我将如何解决

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, TimeoutException

TIME_TIMEOUT = 20 # Twenty-second timeout default

def eprint(*args, **kwargs):
    """ Prints an error message to the user in the console (prints to sys.stderr), passes
    all provided args and kwargs along to the function as usual. Be aware that the 'file' argument
    to print can be overridden if supplied again in kwargs.
    """
    print(*args, file=sys.stderr, **kwargs)


def login(driver):
    global _email, _password
    try:
        email = WebDriverWait(driver, TIME_TIMEOUT).until(EC.presence_of_element_located((By.XPATH, "//input[@id='user_email']")))
        pw = WebDriverWait(driver, TIME_TIMEOUT).until(EC.presence_of_element_located((By.XPATH, "//input[@id='password']"))
        pw.submit()
        # if this doesn't work try the following:
        # btn_submit = WebDriverWait(driver, TIME_TIMEOUT).until(EC.element_to_be_clickable((By.XPATH, "//button[@track-element='click-for-login']"))
        # btn_submit.click() 
        # if that doesn't work, try to add some random wait times using the 
        # sleepyTime() example from above to add some artificial waiting to your email entry, your password entry, and the attempt to submit the form.

except NoSuchElementException as ex:
    eprint(ex.msg())

except TimeoutException as toex:
    eprint(toex.msg)

if __name__ == '__main__':
    driver = webdriver.Chrome('/usr/bin/chromium/chromedriver',chrome_options=chrome_options)
    #d.get('https://www.google.nl/')
    #driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get('https://www.goeventz.com/')
    if login(driver) is not None:
        print(create_event(driver))

答案 4 :(得分:0)

对于无头chrome浏览器,您还需要在chrome选项中提供窗口大小。对于无头浏览器selenium无法知道您的窗口大小,请尝试并告诉我。

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('window-size=1920x1480')