为什么 Selenium 找不到我在代码中指定的元素,即使它在 HTML 中?

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

我正在学习如何使用 ChromeDriver 在 Python 3.9.2 上使用 Selenium 自动浏览网站,但我被困在 GitHub 的登录页面,这是我正在练习的网站。

这是我用来自动登录的代码:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
browser = webdriver.Chrome(chrome_options)
browser.get("https://github.com")`
    
sign_in_link = browser.find_element(By.LINK_TEXT, "Sign in")
sign_in_link.click()
username_box = browser.find_element(By.ID, "login_field")
username_box.send_keys("<username>")
password_box = browser.find_element(By.NAME, "password")
password_box.send_keys("<password>")
password_box.submit()

现在,当我执行此代码时,这是我得到的异常:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: {"method":"css selector", "selector":"\[id="login_field"\]"}

我尝试用

(By.ID, "login_field")
替换
(By.NAME, "login")
但我仍然得到相同的异常,说它找不到该元素。当我检查网页上的元素时,它显示以下内容:

<input type="text" name="login" id="login_field" class="form-control input-block js-login- field" autocapitalize="off" autocorrect="off" autocomplete="username" autofocus="autofocus" required="required">

我相信我为函数 find_element() 使用了正确的参数,但 Selenium 找不到元素,但如果我手动登录,它可以正常工作。 我还尝试使用完整的 XPath 作为函数 find_element() 的参数,如下所示:

username_box = browser.find_element(By.XPATH, "/html/body/div\[1\]/div\[3\]/main/div/div\[4\]/form/input\[3\]")

我第一次运行代码时有效,但当我再次尝试时,抛出了相同的异常,表示找不到该元素。关于如何成功地一致地自动登录有什么想法吗?

python html selenium-chromedriver browser-automation
1个回答
0
投票

我认为你的程序的问题是它在打开页面后尝试立即填充输入字段。登录名和密码元素不会立即出现,稍后会在 JavaScript 的帮助下出现。所以你要等到它发生。 Selenium 为此提供了工具:

selenium.webdriver.support.wait.WebDriverWait
selenium.webdriver.support.expected_conditions

这是代码的工作版本,与最初的版本没有太大区别:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import element_to_be_clickable

chrome_options = Options()
chrome_options.add_experimental_option("detach", True)
browser = webdriver.Chrome(chrome_options)
browser.get("https://github.com")

sign_in_link = browser.find_element(By.LINK_TEXT, "Sign in")
sign_in_link.click()
username_box = WebDriverWait(browser, 10).until(
    element_to_be_clickable((By.ID, "login_field"))
)
username_box.send_keys("<username>")
password_box = browser.find_element(By.NAME, "password")
password_box.send_keys("<password>")
password_box.submit()

这是我实际使用的代码版本:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import element_to_be_clickable

d = webdriver.Chrome()
d.get('https://github.com/login')

u = WebDriverWait(d, 10).until

u(element_to_be_clickable((By.CSS_SELECTOR, '#login_field'))).send_keys('<username>')
password_element = u(element_to_be_clickable((By.CSS_SELECTOR, '#password')))
password_element.send_keys('<password>')
password_element.submit()

© www.soinside.com 2019 - 2024. All rights reserved.