Selenium 可以输入字段但无法输入特定字段

Selenium can type in fields but is unable to type in a specific field

driver.find_element_by_id('username').send_keys('thisIsAString') Selenium 可以输入密码字段,但不能输入用户名字段。我对它们都使用了相同的代码,但出于某种原因,用户名表现得很奇怪。

<input placeholder="Choose username" required="" name="username" messages="[object Object]" iframename="top" pattern=".{1,40}" id="username" class="input">

也就是用户名字段的HTML
任何帮助将不胜感激!

编辑:
代码:

from selenium import webdriver
import time

url = 'https://protonmail.com/signup'

driver = webdriver.Chrome('chromedriver')
driver.get(url)



time.sleep(2)

driver.find_element_by_class_name('panel-heading').click()

time.sleep(4)

driver.find_element_by_id('freePlan').click()

time.sleep(20)

driver.find_element_by_id('username').send_keys('thisIsAString')

time.sleep(1.5)

driver.find_element_by_id('password').send_keys('passwordForUser')

time.sleep(2)

driver.find_element_by_id('passwordc').send_keys('passwordForUser')

time.sleep(2)

driver.find_element_by_class_name('signUpProcess-btn-create').click()

time.sleep(1)

driver.find_element_by_id('confirmModalBtn').click()

错误消息:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"id","selector":"username"}(第 21 行)

您的输入字段尚未加载,但代码正在访问它。您可以使用以下代码等待输入字段加载完毕。然后就可以访问了。

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

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "username"))
    )
finally:
    driver.quit()

通常在访问页面上的任何元素之前始终确保您的页面已完全加载。


更新: 我刚刚看到您在这里使用 iFrame。尝试向 iFrame 标记添加一个 ID,然后像这样等待它加载:

HTML:

<iframe id="iFrameTagID" title="Registration form" scrolling="no" class="top" data-name="top" sandbox="allow-scripts allow-same-origin allow-popups allow-top-navigation" src="https://secure.protonmail.com/abuse.iframe.html?name=top"></iframe>

硒:

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

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, "iFrameTagID"))
    )
finally:
    driver.quit()

我可以看到您的页面中有几个 iFrame。此外,由于它的 Ajax 页面很多组件是单独加载的,所以这里最好的选择是 explicitwait。注意,time.sleep() 不是一个非常可靠的等待方法,它将使您的测试不可预料的。使用以下代码:

driver.get("https://protonmail.com/signup")
#Wait for upto 30 sec for Free plan div to appear
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.XPATH, "//div[@aria-controls='plan-free']"))).click()

#Wait for upto 30 sec for Select Free plan button to appear
WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, "freePlan"))).click()
#Wait and switch to iframe containing user id field
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title ='Registration form' and @class='top']")))
WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.ID, "username")))
driver.find_element_by_id('username').send_keys("abc")
driver.switch_to.default_content() # Switch to default window
driver.find_element_by_id('password').send_keys("abc")
driver.find_element_by_id('passwordc').send_keys("abc")

请注意,如果您希望输入恢复电子邮件并单击“创建帐户”按钮,则需要切换另一个 iframe。使用如下:

#To enter recovery Email and click on create account button
WebDriverWait(driver, 30).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@title ='Registration form' and @class='bottom']")))
driver.find_element_by_id('notificationEmail').send_keys("xyz")
driver.find_element_by_name('submitBtn').click()
driver.switch_to.default_content()