使用Selenium(Python 2.7)在隐藏元素上输入数据-元素不可见

使用Selenium(Python 2.7)在隐藏元素上输入数据-元素不可见,python,selenium,Python,Selenium,我正在编写一个脚本,使用Selenium和Python 2.7登录我的银行帐户。从历史上看,它是有效的,但是现在它抛出一个ElementNotVisibleException异常。这是我的代码: import time import os import subprocess from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support

我正在编写一个脚本,使用Selenium和Python 2.7登录我的银行帐户。从历史上看,它是有效的,但是现在它抛出一个ElementNotVisibleException异常。这是我的代码:

import time
import os 
import subprocess
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import ui

user_id = raw_input('Enter your account number')
password = raw_input('Enter your password')

driver = webdriver.Chrome()  # Optional argument, if not specified will search path.

def regular():

    site = driver.get('https://www.meridiancu.ca/');

    enter_user_id = driver.find_element_by_xpath('//*[@id="memberNo"]').send_keys(user_id)

regular()
下面是我的错误消息:

Traceback (most recent call last):
  File "C:\Users\Desktop\Programming\Python Files\Monthly\Banking.py", line 50, in <module>
    regular()
  File "C:\Users\Desktop\Programming\Python Files\Monthly\Banking.py", line 19, in regular
    enter_user_id = driver.find_element_by_xpath('//*[@id="memberNo"]').send_keys(user_id)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", line 349, in send_keys
    'value': keys_to_typing(value)})
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webelement.py", line 493, in _execute
    return self._parent.execute(command, params)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "C:\Python27\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
ElementNotVisibleException: Message: element not visible**
  (Session info: chrome=63.0.3239.84)
  (Driver info: chromedriver=2.30.477700 (0057494ad8732195794a7b32078424f92a5fce41),platform=Windows NT 10.0.16299 x86_64)
回溯(最近一次呼叫最后一次):
文件“C:\Users\Desktop\Programming\Python Files\Monthly\Banking.py”,第50行,在
正规的
文件“C:\Users\Desktop\Programming\Python Files\Monthly\Banking.py”,第19行,常规格式
输入\u user\u id=driver。通过\u xpath('/*[@id=“memberNo”]')查找\u元素。发送\u密钥(user\u id)
文件“C:\Python27\lib\site packages\selenium\webdriver\remote\webelement.py”,第349行,位于发送键中
“值”:键到键入(值)})
文件“C:\Python27\lib\site packages\selenium\webdriver\remote\webelement.py”,第493行,在\u execute中
返回self.\u parent.execute(命令,参数)
文件“C:\Python27\lib\site packages\selenium\webdriver\remote\webdriver.py”,第256行,执行
self.error\u handler.check\u响应(响应)
文件“C:\Python27\lib\site packages\selenium\webdriver\remote\errorhandler.py”,第194行,在check\u响应中
引发异常类(消息、屏幕、堆栈跟踪)
ElementNotVisibleException:消息:元素不可见**
(会话信息:chrome=63.0.3239.84)
(驱动程序信息:chromedriver=2.30.477700(0057494ad8732195794a7b32078424f92a5fce41),平台=Windows NT 10.0.16299 x8664)

异常被抛出在
enter\u user\u id=driver.find\u element\u by_xpath('/*[@id=“memberNo”]')
我主要熟悉C,因此您可能需要花一点时间来查找确切的方法翻译,但我建议您:

首先,看看您正在查找的元素是否实际不是您想要的(应该有一个element.Highlight()方法,或者该方法是否不适用于element.Location)

然后,查看它是否有子对象屏蔽它(如果有,则单击它们)

如果不起作用,请将鼠标移动到元素的位置并单击它


请随时询问我您是否需要帮助来实现此功能,因为您的xpath可以匹配5个元素,并且第一个元素是隐藏的,这就是报告“ElementNotVisiableException”的原因

为什么你的脚本以前有效,但现在有效。我认为该网站重新设计,现在它支持响应,以适应不同的浏览器大小。对于不同的浏览器大小,用户ID有5个输入框

改为

enter_user_id = driver.find_element_by_css_selector('div.desktop input[name="memberNo"]').send_keys(user_id)

请先在浏览器DevTool中手动测试css选择器:
div.desktop input[name=“memberNo”]
,以确认它可以在您的浏览器大小下工作。如果它不能工作,请自行更改css选择器。

问题是有5个
输入
标记,每个标记的id都是
成员号
,但只有一个可见。我过去在这样一个场景中所做的是获取与该定位器匹配的元素集合,并将列表过滤到只有可见的元素。列表中应该只有一个元素,即您想要的元素。那应该看起来像

memberNos = filter(lambda e: e.is_displayed(), driver.find_elements_by_css_selector("#memberNo"))
memberNos[0].send_keys(user_id)

当您试图用
xpath
成员编号/用户ID字段标识为
/*[@ID=“memberNo”]
时,此
xpath
HTML
中的5元素完全匹配。因此,我们需要构造一个唯一的
css
xpath
,它将唯一地标识成员编号/用户ID字段,如下所示:

  • xpath

    driver.find_element_by_xpath("//div[@class='homepage-banner-block-grx desktop']//input[@id='memberNo' and @type='text']").send_keys(user_id)
    
    driver.find_elements_by_css_selector("div.homepage-banner-block-grx.desktop input#memberNo[type=text]").send_keys(user_id)  
    
  • css\u选择器

    driver.find_element_by_xpath("//div[@class='homepage-banner-block-grx desktop']//input[@id='memberNo' and @type='text']").send_keys(user_id)
    
    driver.find_elements_by_css_selector("div.homepage-banner-block-grx.desktop input#memberNo[type=text]").send_keys(user_id)  
    
注意

  • 在构造
    xpath
    时,确保我们需要避免
    开始跳转内容链接
    部分、
    移动导航
    部分和使用
    移动按钮
    类中的成员编号/用户ID字段

  • 我们还需要确保
    xpath
    标识文本字段,而不是任何隐藏字段

  • 最后,如果在元素上调用
    send\u keys(user\u id)
    方法,它将返回void


这并不能回答问题。成员编号/用户ID字段可以通过一个简单的
find_element_by_xpath()
find_element_by_css_selector()
找到,在这里您通过
find_element_by_css_selector()
以复杂的方式创建列表。您提到了
5个输入标记
。虽然您已经考虑了
display()
元素,但是列表中的第一个元素仍然不是预期的元素,因为您没有考虑到
登录mobile
类。如果您理解它,它会回答问题。问题是页面上有5个输入都具有相同的ID,但在任何给定时间只有一个可见。随着站点大小的更改,显示的元素也会更改。这种方法很灵活,但仍然很简单,只查找显示的输入,无论站点的大小/模式如何,都会这样做。第一行获取所有5个输入,并将它们过滤到仅显示的一个。第二行只获取列表中的第一个(也是唯一一个)元素并将文本发送给它。我已经解释了您考虑的所有步骤,
似乎不符合OP的要求。他的要求是找到元素。我已经提供了一种方法来做到这一点,无论他计划在未来使用的网站或设备的大小,所以它是灵活的和不受未来影响的。我在两行中完成了它,而你在一行中完成了你的,但它只会在桌面站点上找到元素。随着站点大小的调整,该站点的设计会发生变化。此定位器仅在站点处于“桌面模式”时工作。如果浏览器因未最大化而变小,或者手机/平板电脑测试已完成,则找不到可见元素。它是阿尔瓦