2011-09-23 133 views
16

因此,我對Selenium如何做到這一點感到十分困惑,並且無法在任何地方找到答案,所以我分享了我的經驗。使用python selenium選擇iframe

我試圖選擇一個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代碼(使用硒庫)試圖以此來找到這個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") 

反覆失敗,硒命令的每個組合我能找到。偶爾的成功不會是可重複的,也許這是某種競爭條件或某種事情?從來沒有找到正確的方法讓它適應硒。

回答

6

最後什麼工作對我來說是:

 sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();") 

基本上不使用硒發現在iframe中的鏈接,點擊就可以了;使用jQuery。 Selenium有能力運行一個任意的javascript顯然(這是python-selenium,我猜原來的selenium命令是runScript或其他東西),一旦我可以使用jQuery,我可以這樣做:Selecting a form which is in an iframe using jQuery

+3

你最好使用Selenium的getEval命令(可能是Python綁定中的「get_eval」)而不是其runScript命令。 getEval在JavaScript代碼完成之前不會返回,而runScript簡單插入

1

Selenium的selectFrame命令接受所有標準定位器,如css=,但它也有一組額外的定位器,專門用於FRAME和IFRAME元素。

作爲the doc說:

selectFrame(定位器)選擇當前窗內的幀。 (您可以多次調用此命令來選擇嵌套幀。) 要選擇父幀,請使用「relative = parent」作爲定位器;到 選擇頂部框架,使用「相對=頂部」。您也可以通過基於0的索引號選擇一個幀 ;選擇第一個「索引= 0」的幀,或者第二個「索引= 2」的幀。

您也可以使用DOM的表達來識別要直接 框架,像這樣:dom=frames["main"].frames["subframe"]

參數:定位器 - 一個元素定位標識一個幀或iframe

一般來說,你使用專業定位器會有更好的運氣,尤其是如果您先建立正確的環境(,例如,select_frame("relative=top"); select_frame("id=upload_file_frame");)。

+0

是的,selectFrame沒有爲我工作。這並不意味着它不適用於任何人,但我發現它實際上是在5中選擇了一次。 – rossdavidh

2

你不需要使用JavascriptExecutor。你需要做的全部是開關到框架,然後再切換回來了,就像這樣:

// do stuff on main window 
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更可靠。

28

這對Python有用(v。2.7),藉助iframe測試,並試圖在iframe中插入數據時的webdriver &硒:

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

不知何故,當用xpath搜索時,WebDriver會將元素放入iframe中。我試過通過CSS,ID找到元素,但它總是給我一個不存在元素的錯誤(實際上因爲我使用了waitForElement命令而導致超時失敗)。我沒有想到用xpath搜索元素會有所作爲,但幸運的是,當我用完了想法之後,嘗試了一下。非常感謝! – GOstrowsky

+5

'driver.switch_to_frame()'現在不推薦使用,請使用'driver.switch_to.frame()' –

0

這裏是一個工作的教程,幫助您瞭解如何處理使用硒的webdriver與Python網頁上的I幀: https://www.youtube.com/watch?v=sfdWF4vBZ2o

這個命令是用來處理I幀: driver.switch_to.frame(frame_id)

2

如果iframe是動態的節點,它也可以等待iframe appeare NCE明確,然後切換它使用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() 
相關問題