使用 Python + Selenium 选择 iframe

2024-12-17 08:30:00
admin
原创
166
摘要:问题描述:所以,我对如何在 Selenium 中做到这一点感到非常困惑,并且无法在任何地方找到答案,所以我分享了我的经验。我尝试选择一个 iframe,但没有成功(或者无论如何都无法重复)。HTML 是:<iframe id="upload_file_frame" width=&qu...

问题描述:

所以,我对如何在 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 命令组合都会重复失败。

偶尔的成功无法重现,所以也许是某种竞争条件之类的?从来没有找到在 selenium 中正确获取它的正确方法。


解决方案 1:

当我使用 Python (v. 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()

解决方案 2:

如果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找到常见的 WebElement :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()

解决方案 3:

最终对我有用的是:

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

基本上,不要使用 selenium 来查找 iframe 中的链接并单击它;使用 jQuery。Selenium 显然能够运行任意一段 javascript(这是 python-selenium,我猜原始 selenium 命令是 runScript 之类的),一旦我可以使用 jQuery,我就可以执行以下操作:使用 jQuery 选择 iframe 中的表单

解决方案 4:

您不需要使用 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 更可靠。

解决方案 5:

要转移Selenium的焦点,<iframe>您可以使用以下任一定位器策略:

  • 使用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

参考

您可以在以下位置找到几个相关的讨论:

  • iframe 下 #document 的处理方法

  • 通过 Selenium 和 python 切换到 iframe

解决方案 6:

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");

解决方案 7:

您可以使用这个简单的代码通过 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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用