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

问题描述 投票:0回答:4

我理解这个问题已被问到但我需要一些解决方案来解决这个错误:

 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存在一些问题,但我不知道如何解决这个问题。我尝试了所有可能的解决方案.............

python-3.x selenium selenium-webdriver webdriver webdriverwait
4个回答
1
投票

而不是使用login.send_keys(Keys.ENTER)你应该使用selenium click()方法,这将适合你。

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

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@track-element='header-login']"))).click()

1
投票

此错误消息...

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

...意味着当您尝试在其上调用click()时,所需元素无法进行交互。

几个事实:

  • 初始化Chrome浏览器时始终处于最大化模式。
  • 您可以禁用扩展程序。
  • 您还需要禁用-inobobars。

我使用了您构建的相同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


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变量全局化,除非它们在登录功能的某处被更改,并且你希望该更改被推广到其他范围。

我将如何尝试解决它

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

1
投票

对于无头镀铬浏览器,您需要在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')
© www.soinside.com 2019 - 2024. All rights reserved.