如何在 Selenium Webdriver 中处理 iFrames:switchTo()
Selenium Webdriver 中的 iFrame
Selenium Webdriver 中的 iFrame 是一个嵌入在另一个网页中的网页或内联框架,或嵌入在另一个 HTML 文档中的 HTML 文档。iFrame 通常用于将其他来源(如广告)的内容添加到网页中。iFrame 使用 <iframe> 标签定义。
如何识别 iFrame
我们无法通过仅仅查看页面或使用 Firebug 检查来检测框架。
观察下图,显示的广告是一个 Iframe,我们无法通过 Firebug 检查来定位或识别它。那么问题是,您如何识别 iFrame?

我们可以使用以下方法在 Selenium 中识别框架
- 右键单击元素,如果找到“此框架”之类的选项,那么它就是一个 iFrame。(请参阅上图)
- 右键单击页面并单击“查看页面源代码”,然后搜索“iframe”,如果能找到任何带有“iframe”的标签名,则表示该页面包含一个 iFrame。
在上图中,您可以看到右键单击后,“此框架”选项可用,因此我们现在确定它是一个 iFrame。
我们甚至可以使用以下代码片段识别 iFrame 的总数。
Int size = driver.findElements(By.tagName("iframe")).size();
如何使用 WebDriver 命令在 Selenium 中处理框架
基本上,我们可以通过 3 种方式切换元素并在 Selenium 中处理框架。
- 按索引
- 按名称或 ID
- 按网页元素
方法 1:按索引切换到框架
索引是 Selenium 中处理框架的属性之一,通过它我们可以切换到框架。
iframe 的索引从“0”开始。
假设页面中有 100 个框架,我们可以通过使用索引切换到 Selenium 中的框架。
driver.switchTo().frame(0);
driver.switchTo().frame(1);
方法 2:按名称或 ID 切换到框架
Name 和 ID 是在 Selenium 中处理框架的属性,通过它们我们可以切换到 iFrame。
driver.switchTo().frame("iframe1");
driver.switchTo().frame("元素的 ID");
通过 ID 切换到 iFrame 的示例
通过网页元素切换到框架
我们可以通过以下 URL 访问此 iFrame:https://demo.guru99.com/test/guru99home/
由于它是一个 iFrame,因此无法直接通过 XPath 点击 iFrame。我们必须先切换到框架,然后才能使用 XPath 进行点击。
步骤 1)
WebDriver driver = new FirefoxDriver(); driver.get("https://demo.guru99.com/test/guru99home/"); driver.manage().window().maximize();
- 我们初始化 Firefox 驱动程序。
- 导航到包含 iFrame 的“guru99”网站。
- 最大化窗口。
步骤 2)
driver.switchTo().frame("a077aa5e");
- 在此步骤中,我们需要通过 Firebug 检查找出 iFrame 的 ID。
- 然后通过 ID 切换到 iFrame。
步骤 3)
driver.findElement(By.xpath("html/body/a/img")).click();
- 在这里我们需要找出要点击的元素的 XPath。
- 使用上面显示的 Web 驱动程序命令单击元素。
这是完整的代码
public class SwitchToFrame_ID { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); //navigates to the Browser driver.get("https://demo.guru99.com/test/guru99home/"); // navigates to the page consisting an iframe driver.manage().window().maximize(); driver.switchTo().frame("a077aa5e"); //switching the frame by ID System.out.println("********We are switch to the iframe*******"); driver.findElement(By.xpath("html/body/a/img")).click(); //Clicks the iframe System.out.println("*********We are done***************"); } }
输出
浏览器导航到包含上述 iFrame 的页面并点击 iFrame。
方法 3:按网页元素切换到框架
我们甚至可以使用网页元素切换到 iFrame。
driver.switchTo().frame(WebElement);
如何切换回主框架
我们必须退出 iFrame。
要返回父框架,您可以使用 switchTo().parentFrame(),或者如果您想返回主框架(或最上层父框架),您可以使用 switchTo().defaultContent();
driver.switchTo().parentFrame(); driver.switchTo().defaultContent();
如果我们无法使用 ID 或网页元素切换框架,该怎么办
假设页面中有 100 个框架,并且没有可用的 ID,在这种情况下,我们不知道所需元素是从哪个 iFrame 加载的(这也是我们不知道框架索引的情况)。
针对上述问题的解决方案是,我们必须通过以下代码片段找到加载元素的 iFrame 的索引,然后我们需要通过索引切换到 iFrame。
以下是使用以下代码片段查找加载元素的框架索引的步骤
步骤 1)
WebDriver driver = new FirefoxDriver(); driver.get("https://demo.guru99.com/test/guru99home/"); driver.manage().window().maximize();
- 初始化 Firefox 驱动程序。
- 导航到包含 iFrame 的“guru99”网站。
- 最大化窗口。
步骤 2)
int size = driver.findElements(By.tagName("iframe")).size();
- 上述代码使用标签名“iframe”查找页面中存在的 iFrame 总数。
步骤 3)
此步骤的目标是找出 iFrame 的索引。
for(int i=0; i<=size; i++){ driver.switchTo().frame(i); int total=driver.findElements(By.xpath("html/body/a/img")).size(); System.out.println(total); driver.switchTo().defaultContent();}
上述“for 循环”遍历页面中的所有 iFrame,如果找到所需的 iFrame 则打印“1”,否则返回“0”。
这是第 3 步之前的完整代码
public class IndexOfIframe { public static void main(String[] args) { WebDriver driver = new FirefoxDriver(); driver.get("https://demo.guru99.com/test/guru99home/"); driver.manage().window().maximize(); //driver.manage().timeouts().implicitlyWait(100, TimeUnit.SECONDS); int size = driver.findElements(By.tagName("iframe")).size(); for(int i=0; i<=size; i++){ driver.switchTo().frame(i); int total=driver.findElements(By.xpath("html/body/a/img")).size(); System.out.println(total); driver.switchTo().defaultContent();}}}
执行此程序,输出将如下所示
输出
1 0 0 0 0 0
验证输出,您会发现一系列的 0 和 1。
- 在输出中找到“1”的地方就是加载元素的框架索引。
- 由于 iFrame 的索引从“0”开始,如果您在第一个位置找到 1,则索引为 0。
- 如果您在第三个位置找到 1,则索引为 2。
一旦找到索引,我们可以注释掉 for 循环。
步骤 4)
driver.switchTo().frame(0);
- 一旦找到元素的索引,您就可以使用上述命令切换框架。
- driver.switchTo().frame(从步骤 3 中找到的索引);
步骤 5)
driver.findElement(By.xpath("html/body/a/img")).click();
- 上述代码将点击 iFrame 或 iFrame 中的元素。
因此,完整的代码将如下所示
public class SwitchToframe { public static void main(String[] args) throws NoSuchElementException{ WebDriver driver = new FirefoxDriver(); driver.get("https://demo.guru99.com/test/guru99home/"); driver.manage().window().maximize(); //int size = driver.findElements(By.tagName("iframe")).size(); /*for(int i=0; i<=size; i++){ driver.switchTo().frame(i); int total=driver.findElements(By.xpath("html/body/a/img")).size(); System.out.println(total); driver.switchTo().defaultContent(); //switching back from the iframe }*/ //Commented the code for finding the index of the element driver.switchTo().frame(0); //Switching to the frame System.out.println("********We are switched to the iframe*******"); driver.findElement(By.xpath("html/body/a/img")).click(); //Clicking the element in line with Advertisement System.out.println("*********We are done***************"); } }
输出
浏览器导航到包含上述 iFrame 的页面并点击 iFrame。
Selenium 中嵌套框架的概念
假设有两个框架相互嵌套,如下图所示,我们的要求是打印外部框架和内部框架中的文本。
在嵌套框架的情况下,
- 首先,我们必须通过 iFrame 的索引或 ID 切换到外部框架
- 一旦我们切换到外部框架,我们就可以找到外部框架中 iFrame 的总数,并且
- 我们可以通过任何已知方法切换到内部框架。
退出框架时,我们必须按照进入的相同顺序退出,即先内部框架,然后是外部框架。
上述嵌套框架的 HTML 代码如下所示。
上述 HTML 代码清楚地解释了另一个 iFrame 标签内的 iFrame 标签(以绿色突出显示),表明存在嵌套 iFrame。
以下是切换到外部框架并打印外部框架文本的步骤
步骤 1)
WebDriver driver=new FirefoxDriver(); driver.get("Url"); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); int size = driver.findElements(By.tagName("iframe")).size(); System.out.println("Total Frames --" + size); // prints the total number of frames driver.switchTo().frame(0); // Switching the Outer Frame System.out.println (driver.findElement(By.xpath("xpath of the outer element ")).getText());
- 切换到外部框架。
- 打印外部框架上的文本。
一旦我们切换到外部框架,我们应该知道外部框架内是否存在任何内部框架
步骤 2)
size = driver.findElements(By.tagName("iframe")).size(); // prints the total number of frames inside outer frame System.out.println("Total Frames --" + size);
- 查找外部框架内 iFrame 的总数。
- 如果大小为“0”,则框架内没有内部框架。
步骤 3)
driver.switchTo().frame(0); // Switching to innerframe System.out.println(driver.findElement(By.xpath("xpath of the inner element ")).getText());
- 切换到内部框架
- 打印内部框架上的文本。
这是完整的代码
public class FramesInsideFrames { public static void main(String[] args) { WebDriver driver=new FirefoxDriver(); driver.get("Url"); driver.manage().window().maximize(); driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); int size = driver.findElements(By.tagName("iframe")).size(); System.out.println("Total Frames --" + size); // prints the total number of frames driver.switchTo().frame(0); // Switching the Outer Frame System.out.println (driver.findElement(By.xpath("xpath of the outer element ")).getText()); //Printing the text in outer frame size = driver.findElements(By.tagName("iframe")).size(); // prints the total number of frames inside outer frame System.out.println("Total Frames --" + size); driver.switchTo().frame(0); // Switching to innerframe System.out.println(driver.findElement(By.xpath("xpath of the inner element ")).getText()); //Printing the text in inner frame driver.switchTo().defaultContent(); } }
输出:
上述代码的输出将打印内部框架和外部框架中的文本。