提问人:achille 提问时间:10/29/2023 最后编辑:tripleeeachille 更新时间:10/29/2023 访问量:37
如何在 protonmail.com 上访问iframe中的消息字段?
How to access message field inside iframe on protonmail.com?
问:
我正在尝试在 Protonmail 服务器上使用 Python Selenium 发送电子邮件。一切正常,直到我收到电子邮件。
要访问电子邮件字段,我使用以下 xpath:。当通过 DOM 手动搜索时,它会给出一个独特的元素(Chromium 也给出相同的 xpath)。"//div[@id='rooster-editor']/div[1]"
但是在脚本中,此 XPath 会抛出“没有此类元素”异常。我首先认为该错误是由页面未完全加载的事实引起的,如这篇文章中所述:Selenium Webdriver - NoSuchElementExceptions。
为了避免这个问题,我插入了一个 20 秒 ,但问题仍然存在。implicitly_wait
我也不认为这个功能可以解决这个问题:因为我的片段比手动发送电子邮件慢。EC.presence_of_element_located(By.XPATH,"//div[@id='rooster-editor']/div[1]"
总而言之,这是我在代码片段中引入一些“等待”或“时间睡眠”的地方:从单击“新消息”按钮 - >隐式等待 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')
答:
消息区域放置在带有选择器的 iframe 中。[data-testid=rooster-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()
评论