唯一元素没有此类元素例外

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

我正在尝试在 protonmail 服务器上使用 python selenium 发送电子邮件。一切正常,直到我收到电子邮件为止。

要访问电子邮件字段,我使用以下 xpath:

"//div[@id='rooster-editor']/div[1]"
。当通过 DOM 手动搜索时,它给出了一个唯一的元素(chromium 也给出了相同的 xpath)。

但在脚本中,此 XPath 会引发“没有此类元素”异常。我首先认为该错误是由于页面未完全加载而引起的,如本文中所述:Selenium Webdriver - NoSuchElementExceptions。 为了避免这个问题,我插入了 20 秒的implicitly_wait,但问题仍然存在。

我认为这个功能也不能解决问题:

EC.presence_of_element_located(By.XPATH,"//div[@id='rooster-editor']/div[1]"
因为我的代码片段比手动发送电子邮件慢。

总而言之,我在代码片段中引入了一些“等待”或“time.sleep”:从单击“新消息”按钮 -> 隐式等待 20 秒 -> 填写收件人电子邮件 -> 2 秒睡眠 -> 电子邮件主题 -> 3 秒睡眠 -> 然后发送电子邮件。因此,我认为问题可能不是由未完全加载的页面引起的。

所以我的问题是:什么会带来这样的异常?

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

class FindProton():
    def test(self, recipient, subject, msg):
        self.recipient = recipient
        self.subject = subject
        self.msg = msg
        baseUrl = 'https://www.protonmail.com'
        driver = webdriver.Firefox()
        driver.get(baseUrl)
        driver.maximize_window()
        driver.implicitly_wait(5)
        time.sleep(2)

        #SIGN IN 
        elementXpath = driver.find_element(By.XPATH,"//span[text()='Sign in']") 
        elementXpath.click()

        #USERNAME 
        time.sleep(3)
        #elementId_0 = driver.find_element(By.ID,'username').click()
        elementId_0 = driver.find_element(By.ID,'username')
        #elementId_0.send_keys(self.user)
        elementId_0.send_keys('xxxxxxx')

        #PASSWORD
        time.sleep(1)
        elementId_1 = driver.find_element(By.ID,'password')
        #elementId_1.send_keys(self.passwd)
        elementId_1.send_keys('xxxxxx')

        time.sleep(2)
        elementId_2 = driver.find_element(By.XPATH,"//button[text()='Sign in']")
        elementId_2.click()

        #my router is the hell slow so I introduce a long implicit wait...
        driver.implicitly_wait(20)
        #time.sleep(1)
        elementId_3 = driver.find_element(By.XPATH,"//button[text()='New message']")
        elementId_3.click()

        driver.implicitly_wait(15)
        #recipient ; part of id=dynamic, so use id contains 
        element_4 = driver.find_element(By.XPATH,"//input[contains(@id,'to-composer-')]")
        element_4.send_keys(self.recipient)

        time.sleep(2)
        #subject, part of id = dynamic, so use id contains 
        element_5 = driver.find_element(By.XPATH,"//input[contains(@id,'subject-composer-')]")
        element_5.send_keys(self.subject)
           
        time.sleep(3)
        #email message: BUG HERE !
        element_6 = driver.find_element(By.XPATH,"//div[@id='rooster-editor']/div[1]").click()

ff=FindProton()
ff.test('unkn[email protected]','no subject email','this is a short message')

谢谢大家!

python selenium-webdriver nosuchelementexception
1个回答
0
投票

消息区域通过选择器

[data-testid=rooster-iframe]
放置在 iframe 中。

因此,要访问该元素,您需要先切换到 iframe 内容。

另请注意,该消息不是输入字段,要输入内容,您应该先单击它并模拟键盘操作。

在 iframe 中输入/任何其他操作后,要访问之前的上下文,您应该切换到默认上下文。

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time

   #your code
   action_chains = ActionChains(driver)
   message_frame = driver.find_element(By.CSS_SELECTOR, '[data-testid=rooster-iframe]')
   driver.switch_to.frame(message_frame)

   element_6 = driver.find_element(By.XPATH, "//div[@id='rooster-editor']/div[1]")
   element_6.click()
   action_chains.send_keys(msg).perform()
   # if you finished with actions inside iframe - add line below
   driver.switch_to.default_content()
© www.soinside.com 2019 - 2024. All rights reserved.