Selenium脚本在逐行执行时起作用,但在完全执行时却不能起作用

时间:2019-12-24 18:03:08

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

我正在尝试使用Python中的Selenium创建一个简单的脚本来执行以下操作:服务器中的IP一旦更改,它将直接进入我的帐户,并使用新的IP更新服务器的IP。到目前为止,一切都很好。在完成最后一步之前,我能够做所有事情。让我向您展示我的代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import os


cwd = os.path.dirname(os.path.realpath(__file__))


d = webdriver.Chrome(cwd + '/chromedriver')
d.get("https://www.noip.com/login")

IP = '11.11.11.11'

username = d.find_element_by_name('username')
username.send_keys('myusername')
password = d.find_element_by_name('password')
password.send_keys('mypassword')

login = d.find_element_by_name('Login')
login.click()

menu = d.find_element_by_link_text('Dynamic DNS')
menu.click()

vpn_name = d.find_element_by_link_text('myserveraddress.hopto.org')
vpn_name.click()

ipv4_address = d.find_elements_by_name('target')

for i in range(0,15):
    ipv4_address[-1].send_keys(Keys.BACKSPACE)
ipv4_address[-1].send_keys(IP)
ipv4_address[-1].send_keys(Keys.ENTER)

d.quit()

现在,当我在Python IDE中逐行执行此代码时,它就像一个符咒。注意:它说ipv4_address[-1].send_keys(Keys.BACKSPACE)的地方是因为树中有2个元素的名称为“ target”,所以我选择了我需要的元素-基本上删除了旧IP的所有值。当它逐行运行时,它在Python IDE中运行良好。但是当我完全运行脚本时,它将始终返回相同的错误:

<selenium.webdriver.remote.webelement.WebElement (session="56796b375703493c63b9857f5f5e2fdc", element="d13d4ffb-af49-47cf-addc-d0c85e70e1cd")>
Traceback (most recent call last):
  File "/Users/jsv/Dropbox/Computer_Science/Python_Scripts/ip_monitor/ip_change.py", line 33, in <module>
    ipv4_address[-1].send_keys(Keys.BACKSPACE)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 479, in send_keys
    'value': keys_to_typing(value)})
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
    return self._parent.execute(command, params)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

我的理解是ElementNotInteractableException是一个异常,通常在显然该项目不可交互时出现,但在这种情况下,它是一个异常!我逐行尝试,效果很好!

有人知道这里出了什么问题吗?

预先感谢

1 个答案:

答案 0 :(得分:3)

我导航到您正在测试的页面,发现一个问题。您的选择器在这里使用:

ipv4_address = d.find_elements_by_name('target')

实际上是在定位2个元素-其中一个可见,而其中一个不可见。我相信位于的第一个元素是隐藏的,而第二个元素是可见的。可以通过检查每个元素的is_displayed()属性来确认。这就是引发您的错误的原因。

enter image description here

有几种方法可以解决此问题。第一个方法是使用Lambda表达式对列表中元素的is_displayed()属性进行过滤:

ipv4_address = d.find_elements_by_name('target')
visible_input = filter(lambda x: x.is_displayed(), ipv4_address)

或者,您可以只使用列表索引来选择第二个元素,在这种情况下这是可见的:

ipv4_address = d.find_elements_by_name('target')
visible_input = ipv4_address[1]

在与元素进行交互之前,我还将在元素上调用WebDriverWait

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC



ipv4_address_elements = WebDriverWait(d, 10).until(EC.presence_of_all_elements_located((By.XPATH, "//input[@name='target']")))

ipv4_address = ipv4_address_elements[1]
相关问题