使用Python和Selenium选择iframe
我在用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代码(使用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命令的组合,但每次都失败。
偶尔成功一次,但又无法重复,所以我在想是不是有什么竞争条件之类的问题?总之,我没找到在Selenium中正确的方法。
7 个回答
30
如果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()
等:
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()
100
我在用Python(版本2.7)、webdriver和Selenium进行测试时,遇到了iframe的问题,想在iframe里面插入数据,这个方法对我有效:
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()
12
最后对我有效的方法是:
sel.run_script("$('#upload_file_frame').contents().find('img[alt=\"Humana\"]').click();")
简单来说,不要用selenium去找iframe里的链接并点击它;用jQuery来做。selenium其实可以运行一些任意的javascript代码(这是python-selenium,我猜原来的selenium命令是runScript之类的),一旦我能用jQuery,就可以像这样操作:用jQuery选择在iframe中的表单