[英]Select iframe using Python + Selenium
所以,我對如何在 Selenium 中做到這一點感到非常困惑,並且在任何地方都找不到答案,所以我分享了我的經驗。
我試圖選擇一個 iframe 並且沒有運氣(或者無論如何都不能重復)。 HTML是:
<iframe id="upload_file_frame" width="100%" height="465px" frameborder="0" framemargin="0" name="upload_file_frame" src="/blah/import/">
<html>
<body>
<div class="import_devices">
<div class="import_type">
<a class="secondary_button" href="/blah/blah/?source=blah">
<div class="import_choice_image">
<img alt="blah" src="/public/images/blah/import/blah.png">
</div>
<div class="import_choice_text">Blah Blah</div>
</a>
</div>
</div>
</body>
</html>
Python 代碼(使用 selenium 庫)試圖使用以下方法找到此 iframe:
@timed(650)
def test_pedometer(self):
sel = self.selenium
...
time.sleep(10)
for i in range(5):
try:
if sel.select_frame("css=#upload_file_frame"): break
except: pass
time.sleep(10)
else: self.fail("Cannot find upload_file_frame, the iframe for the device upload image buttons")
我能找到的每一個 Selenium 命令組合都重復失敗。
偶爾的成功是不可復制的,所以也許是某種競爭條件或什么的? 從來沒有找到正確的方法來正確地獲取硒。
在使用 iframe 進行測試並嘗試在 iframe 中插入數據時,這對我使用 Python (v. 2.7)、webdriver & Selenium 有效:
self.driver = webdriver.Firefox()
## Give time for iframe to load ##
time.sleep(3)
## You have to switch to the iframe like so: ##
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
## Insert text via xpath ##
elem = driver.find_element_by_xpath("/html/body/p")
elem.send_keys("Lorem Ipsum")
## Switch back to the "default content" (that is, out of the iframes) ##
driver.switch_to.default_content()
如果iframe
是動態節點,也可以顯式等待iframe
,然后使用ExpectedConditions
切換到它:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait as wait
driver = webdriver.Chrome()
driver.get(URL)
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("iframe_name_or_id"))
如果iframe
沒有@id
或@name
則可以使用driver.find_element_by_xpath()
、 driver.find_element_by_tag_name()
等將其作為常見的 WebElement 找到:
wait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(driver.find_element_by_xpath("//iframe[@class='iframe_class']")))
從iframe
切換回來:
driver.switch_to.default_content()
最終對我有用的是:
sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();")
基本上不要用selenium在iframe中找到鏈接並點擊; 使用 jQuery。 Selenium 顯然有能力運行任意一段 javascript(這是 python-selenium,我猜原來的 selenium 命令是 runScript 或其他東西),一旦我可以使用 jQuery,我就可以做這樣的事情: 選擇一個表單在 iframe 中使用 jQuery
您不需要使用 JavascriptExecutor。 您需要做的就是切換到框架然后再切換回來,如下所示:
// do stuff on main window
driver.switch_to.frame(frame_reference)
// then do stuff in the frame
driver.switch_to.default_content()
// then do stuff on main window again
只要你小心這一點,你永遠不會有問題。 我唯一一次總是使用 JavascriptExecutor 是為了獲得窗口焦點,因為我認為在這種情況下使用 Javascript 更可靠。
Selenium 的 selectFrame 命令接受所有標准定位器,如css=
,但它還有一組額外的定位器,專門用於 FRAME 和 IFRAME 元素。
正如文檔所說:
selectFrame ( locator )在當前窗口中選擇一個框架。 (您可以多次調用此命令來選擇嵌套框架。)要選擇父框架,請使用“relative=parent”作為定位器; 要選擇頂部框架,請使用“relative=top”。 您還可以通過從 0 開始的索引號來選擇幀; 選擇“index=0”的第一幀,或“index=2”的第三幀。
您也可以使用 DOM 表達式直接標識您想要的框架,如下所示:
dom=frames["main"].frames["subframe"]
參數: locator - 標識框架或 iframe 的元素定位器
一般來說,使用專門的定位器會帶來更好的運氣,特別是如果您首先建立正確的上下文(例如, select_frame("relative=top"); select_frame("id=upload_file_frame");
)。
要在<iframe>
內轉移Selenium的焦點,您可以使用以下任一定位器策略:
使用ID
:
driver.switch_to.frame("upload_file_frame")
使用CSS_SELECTOR
:
driver.switch_to.frame(driver.find_element(By.CSS_SELECTOR, "iframe#upload_file_frame"))
使用XPATH
:
driver.switch_to.frame(driver.find_element(By.XPATH, "//iframe[@id='upload_file_frame']"))
理想情況下,您必須誘導WebDriverWait以獲得所需的框架可用並切換到它,您可以使用以下任一定位器策略:
使用ID
:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"upload_file_frame")))
使用CSS_SELECTOR
:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#upload_file_frame")))
使用XPATH
:
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='upload_file_frame']")))
注意:您必須添加以下導入:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC
您可以在以下位置找到一些相關討論:
您可以使用此簡單代碼使用 xpath 查找 iframe
示例使用 set_iframe("/html/body/div[2]/table/")
def set_iframe(xpath):
print('set_iframe')
driver.switch_to.default_content()
seq = driver.find_elements_by_tag_name('iframe')
for x in range(0, len(seq)):
driver.switch_to.default_content()
print ("iframe-"+str(x))
try:
driver.switch_to.frame(int(x))
driver.find_element_by_xpath(xpath)
return str(x)
except:
continue
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.