按照我在 OP 中的用例,如何使用 Selenium 和 Python 在 iframe 中使用 contenteditable="true" 在輸入欄位中發送文本,我嘗試訪問提交按鈕元素并單擊它。
HTML 看起來像這樣:
<footer data-testid="composer:footer" class="composer-actions flex-item-noshrink flex max-w100">
<div class="flex flex-row-reverse flex-align-self-center w100 ml0-5 mr1-5 pl1-25 pr0-25 mb1">
<div class="button-group button-group-solid-norm button-group-medium" data-testid="composer:send-actions"><button class="button button-group-item button-ghost-weak composer-send-button" aria-busy="false" type="button" data-testid="composer:send-button" aria-describedby="tooltip-19621"><svg viewBox="0 0 16 16" class="icon-16p no-desktop no-tablet on-mobile-flex" role="img" focusable="false"><use xlink:href="#ic-paper-plane"></use></svg><span class="pl1 pr1 no-mobile">Senden</span></button></div>
<div
class="flex flex-item-fluid">
<div class="flex"><button class="button button-for-icon button-ghost-weak mr0-5" aria-busy="false" type="button" data-testid="composer:delete-draft-button" aria-describedby="tooltip-19622"><svg viewBox="0 0 16 16" class="icon-16p" role="img" focusable="false"><use xlink:href="#ic-trash"></use></svg><span class="sr-only">Entwurf l?schen</span></button>
<button
class="button button-for-icon button-ghost-weak mr0-5" aria-busy="false" type="button" data-testid="composer:password-button" aria-pressed="false" aria-describedby="tooltip-19623"><svg viewBox="0 0 16 16" class="icon-16p" role="img" focusable="false"><use xlink:href="#ic-lock"></use></svg><span class="sr-only">Verschlüsselung</span></button><button aria-expanded="false" aria-busy="false" data-testid="dropdown-button" class="editor-toolbar-button interactive composer-toolbar-fontDropDown max-w100 flex flex-align-items-center flex-nowrap button button-for-icon composer-more-dropdown"
type="button" tabindex="-1" title="Weitere Optionen" aria-describedby="tooltip-19625"><svg viewBox="0 0 16 16" class="icon-16p" role="img" focusable="false"><use xlink:href="#ic-ellipsis"></use></svg><span class="sr-only">Weitere Optionen</span></button></div>
<div
class="flex-item-fluid flex pr1"><span class="mr0-5 mauto no-mobile color-weak">Nicht gespeichert</span>
<div class="composer-attachments-button-wrapper flex flex-flex-align-items-center"><label class="button button-for-icon button-ghost-weak inline-block text-center inline-flex" aria-busy="false" role="button" data-testid="composer:attachment-button" aria-describedby="tooltip-19626"><svg viewBox="0 0 16 16" class="icon-16p" role="img" focusable="false"><use xlink:href="#ic-paperclip"></use></svg><input type="file" multiple="" class="composer-attachments-button" data-testid="composer-attachments-button"></label></div>
</div>
</div>
</div>
</footer>
我已經復制了 span 元素的 CSS 選擇器并嘗試了這個:
sendButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "body > div.app-root > div.composer-container > div > div > div > footer > div > div.button-group.button-group-solid-norm.button-group-medium > button > span")))
sendButton.click()
我收到以下錯誤:
selenium.common.exceptions.NoSuchWindowException: Message: Browsing context has been discarded
我不確定我是否針對我想要實作的目標選擇了正確的元素。我經常很難找到針對某個元素的正確策略。如果沒有 id 元素或一個漂亮而簡短的 css 選擇器,最好的方法是什么?我檢查了 Selenium 檔案(https://selenium-python.readthedocs.io/locating-elements.html),但猶豫選擇其中一種建議的方法。
原始代碼:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
myPassword = 'XXXXXXXXXXXXXX!'
browser = webdriver.Firefox() # Opens Firefox webbrowser
browser.get('https://protonmail.com/') # Go to protonmail website
loginButton = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, "a.btn-ghost:nth-child(1)")))
loginButton.click()
usernameElem = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#username")))
usernameElem.send_keys("[email protected]")
passwordElem = browser.find_element_by_css_selector("#password")
passwordElem.send_keys(myPassword)
anmeldenButton = browser.find_element_by_css_selector(".button")
anmeldenButton.click()
newMessage = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[1]/div[3]/div/div/div[1]/div[2]/button")))
newMessage.click()
addressElem = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id^='to-composer']")))
addressElem.send_keys('[email protected]')
subjectElem = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[id^='subject-composer']")))
subjectElem.send_keys('anySubject')
WebDriverWait(browser, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[title='Editor']")))
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#squire"))).send_keys('Test message')
sendButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "body > div.app-root > div.composer-container > div > div > div > footer > div > div.button-group.button-group-solid-norm.button-group-medium > button > span")))
sendButton.click()
browser.switch_to.default_content()
uj5u.com熱心網友回復:
一些初步的評論...
您無需繼續使用
WebDriverWait(browser, 10). 而是宣告一個變數來存盤WebDriverWait實體,wait = WebDriverWait(browser, 10)然后在任何地方使用該變數,例如loginButton = WebDriverWait(browser, 10).until()會成為
loginButton = wait.until()它洗掉了不必要的實體化并使代碼更易于閱讀。
除非您要重用變數,否則只需一行
WebDriverWait()and 操作,例如loginButton = wait.until() loginButton.click()變成
wait.until().click()它減少了您擁有的區域變數的數量,尤其是在您不使用它們時,并且還使代碼更易于閱讀。
主要答案...
我沒有 protonmail 帳戶,但我猜你的最后幾行代碼是問題所在。看起來切換到 IFRAME 后,IFRAME 不再可用...可能是由于.send_keys()? 嘗試browser.switch_to.default_content()在最后.click()一行之前移動,或者您甚至可能不得不切換回默認值,然后切換到新的 IFRAME。這至少應該讓你指出正確的方向。更新了下面的代碼。
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[title='Editor']")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div#squire"))).send_keys('Test message')
browser.switch_to.default_content()
# may need to switch into the correct IFRAME again here
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "body > div.app-root > div.composer-container > div > div > div > footer > div > div.button-group.button-group-solid-norm.button-group-medium > button > span"))).click()
uj5u.com熱心網友回復:
根據截圖:

要識別您需要為element_to_be_clickable()誘導WebDriverWait的元素,您可以使用以下任一Locator Strategies:
使用
CSS_SELECTOR:WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.button-group.button-group-solid-norm.button-group-medium > button span"))).click()
uj5u.com熱心網友回復:
我會嘗試通過 xpath 選擇按鈕。我認為它的方式更準確。如果您使用 chrome 或 fire fox
右鍵單擊瀏覽器上的一個元素
右鍵單擊并通過完整xpath復制和復制
//*[@id="hireme"]/div/ul/li[4]/div/a
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/421998.html
標籤:
