我无法通过Selenium/Python在页面上找到一个元素。

huangapple go评论78阅读模式
英文:

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()

Error

答案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在页面上找到一个元素。


参考资料

您可以在以下讨论中找到一些相关的讨论:

英文:

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:

我无法通过Selenium/Python在页面上找到一个元素。


Reference

You can find a couple of relevant discussions in:

答案2

得分: 1

这是由于网页中的 iframe:

我无法通过Selenium/Python在页面上找到一个元素。

在与内部元素交互之前,您必须先切换到 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:

我无法通过Selenium/Python在页面上找到一个元素。

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&v=2.10.0&account_host=account.mail.ru&type=login&allow_external=1&app_id_mytracker=58519&success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&project=home&from=navi&parent_url=https%3A%2F%2Fmail.ru%2F&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&v=2.10.0&account_host=account.mail.ru&type=login&allow_external=1&app_id_mytracker=58519&success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&project=home&from=navi&parent_url=https%3A%2F%2Fmail.ru%2F&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&v=2.10.0&account_host=account.mail.ru&type=login&allow_external=1&app_id_mytracker=58519&success_redirect=https%3A%2F%2Fe.mail.ru%2Fmessages%2Finbox%3Fback%3D1&project=home&from=navi&parent_url=https%3A%2F%2Fmail.ru%2F&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.

huangapple
  • 本文由 发表于 2023年6月28日 23:56:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76574861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定