英文:
I can't find an element on a page through Selenium/Python
问题
我刚开始学习Selenium,想要在"https://mail.ru/"页面上实现身份验证。有两个"登录"按钮,当点击它们时,会打开一个带有身份验证表单的窗口。然而,Selenium看不到在点击"登录"按钮后出现的页面元素。我已经尝试过使用xPath、class_name等方式进行查找。我该如何解决这个问题?
from selenium.webdriver.common.by import By
import time
class TestLogMail:
def test_log(self, browser_web):
browser_web.get('https://mail.ru/')
time.sleep(3)
button_log = browser_web.find_element(By.XPATH, '//*[@id="mailbox"]/div[1]/button').click()
time.sleep(5)
input_log = browser_web.find_element(By.CSS_SELECTOR, 'input[name="username"]')
input_log.send_keys('mail')
time.sleep(5)
button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div[2]/div[3]/div/div/div[1]/button').click()
time.sleep(5)
input_pass = browser_web.find_element(By.XPATH, '/html/body/div[1]/div[2]/div/div/div/div[2]/div/div/form/div[2]/div/div[2]/div/div/div/div/div/input')
input_pass.clear()
input_pass.send_keys('pass')
time.sleep(5)
button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div/div[3]/div/div/div[1]/div/button').click()
time.sleep(5)
browser_web.save_screenshot('result_log.png')
import pytest
from selenium import webdriver
@pytest.fixture
def browser_web():
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
yield driver
driver.quit()
英文:
I am just starting to learn Selenium and wanted to implement authentication on the "https://mail.ru/" page. There are two "Login" buttons that, when clicked, open a window with an authentication form. However, Selenium does not see the elements of the page that appeared after clicking the "Login" buttons. I have tried searching by xPath, class_name, etc. How can I solve this problem?
from selenium.webdriver.common.by import By
import time
class TestLogMail:
def test_log(self, browser_web):
browser_web.get('https://mail.ru/')
time.sleep(3)
button_log = browser_web.find_element(By.XPATH, '//*[@id="mailbox"]/div[1]/button').click()
time.sleep(5)
input_log = browser_web.find_element(By.CSS_SELECTOR, 'input[name="username"]')
input_log.send_keys('mail')
time.sleep(5)
button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div[2]/div[3]/div/div/div[1]/button').click()
time.sleep(5)
input_pass = browser_web.find_element(By.XPATH, '/html/body/div[1]/div[2]/div/div/div/div[2]/div/div/form/div[2]/div/div[2]/div/div/div/div/div/input')
input_pass.clear()
input_pass.send_keys('pass')
time.sleep(5)
button_input_pass = browser_web.find_element(By.XPATH, '//*[@id="root"]/div/div/div/div[2]/div/div/form/div[2]/div/div[3]/div/div/div[1]/div/button').click()
time.sleep(5)
browser_web.save_screenshot('result_log.png')
import pytest
from selenium import webdriver
@pytest.fixture
def browser_web():
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
yield driver
driver.quit()
答案1
得分: 1
元素“帐户名称”位于<iframe>
内,因此您需要:
-
引导WebDriverWait等待所需的“帧可用并切换到它”。
-
引导WebDriverWait等待所需的“元素可点击”。
-
您可以使用以下任何一种定位策略:
-
使用_CSS_SELECTOR_:
browser_web.get("https://mail.ru/") WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='enter-mail-primary']"))).click() WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src^='https://account.mail.ru/login/?mode=simple']"))) WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='username']"))).send_keys('Daniil')
-
使用_XPATH_:
browser_web.get("https://mail.ru/") WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[@data-testid='enter-mail-primary']"))).click() WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(@src, 'https://account.mail.ru/login/?mode=simple')]"))) WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='username']"))).send_keys('Daniil')
-
-
注意:您必须添加以下导入:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC
-
浏览器快照:
参考资料
您可以在以下讨论中找到一些相关的讨论:
- 通过Selenium和Python切换到iframe
- selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
- Python中的selenium:NoSuchElementException:Message: no such element: Unable to locate element
英文:
The element Account name is within an <iframe>
so you have to:
-
Induce WebDriverWait for the desired frame to be available and switch to it.
-
Induce WebDriverWait for the desired element to be clickable.
-
You can use either of the following locator strategies:
-
Using CSS_SELECTOR:
browser_web.get("https://mail.ru/") WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='enter-mail-primary']"))).click() WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src^='https://account.mail.ru/login/?mode=simple']"))) WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='username']"))).send_keys('Daniil')
-
Using XPATH:
browser_web.get("https://mail.ru/") WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[@data-testid='enter-mail-primary']"))).click() WebDriverWait(browser_web, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[starts-with(@src, 'https://account.mail.ru/login/?mode=simple')]"))) WebDriverWait(browser_web, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='username']"))).send_keys('Daniil')
-
-
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC
-
Browser Snapshot:
Reference
You can find a couple of relevant discussions in:
答案2
得分: 1
这是由于网页中的 iframe:
在与内部元素交互之前,您必须先切换到 iframe。 https://www.selenium.dev/documentation/webdriver/interactions/frames/
iframe = driver.find_element(By.CSS_SELECTOR, "iframe.ag-popup__frame__layout__iframe")
driver.switch_to.frame(iframe)
现在您可以与 iframe 内部的元素交互。
英文:
That's due to the iframe located on that web page:
You must switch to the iframe first before interacting with elements inside. https://www.selenium.dev/documentation/webdriver/interactions/frames/
iframe = driver.find_element(By.CSS_SELECTOR, "iframe.ag-popup__frame__layout__iframe")
driver.switch_to.frame(iframe)
Now you can interact with elements inside the iframe.
答案3
得分: 0
当我点击登录时,我看到它会打开另一个弹出窗口,其中的元素位于一个iframe内。
以下是处理这种情况的步骤:
iframe = driver.find_element_by_xpath('//iframe[@src="https://account.mail.ru/login/?mode=simple&amp;v=2.10.0&amp;account_host=account.mail.ru&amp;type=login&amp;allow_external=1&amp;app_id_mytracker=58519&amp;success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&amp;project=home&amp;from=navi&amp;parent_url=https%3A%2F%2Fmail.ru%2F&amp;responsive=compact"]')
driver.switch_to.frame(iframe)
然后,您可以继续执行您的其余测试步骤。
英文:
As I can see in while clicking on login it is opening another popup and the elements are within an iframe.
<iframe src="https://account.mail.ru/login/?mode=simple&amp;v=2.10.0&amp;account_host=account.mail.ru&amp;type=login&amp;allow_external=1&amp;app_id_mytracker=58519&amp;success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&amp;project=home&amp;from=navi&amp;parent_url=https%3A%2F%2Fmail.ru%2F&amp;responsive=compact" class="ag-popup__frame__layout__iframe" scrolling="no" frameborder="0"></iframe>
Here is you can follow to handle this situation:
iframe = driver.find_element_by_xpath('//iframe[@src="https://account.mail.ru/login/?mode=simple&amp;v=2.10.0&amp;account_host=account.mail.ru&amp;type=login&amp;allow_external=1&amp;app_id_mytracker=58519&amp;success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&amp;project=home&amp;from=navi&amp;parent_url=https%3A%2F%2Fmail.ru%2F&amp;responsive=compact"]')
driver.switch_to.frame(iframe)
And then you can proceed with your rest of the test steps.
I know this xpath is little weired. But you can ask your developer to put an ID to this iframe element which will definitely help to use switch to frame id method directly.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论