2011-09-23 134 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() 
相关问题