如何处理 iFrames Selenium Webdriver: switchTo()
iFrame 中 Selenium 网络驱动程序
iFrame 中 Selenium 网络驱动程序 是嵌入在另一个网页中的网页或内联框架,或嵌入在另一个 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();
如何处理框架 Selenium 使用 WebDriver 命令
基本上,我们可以切换元素并处理框架 Selenium 使用 3 种方法。
- 按索引
- 按名称或 ID
- 通过 Web 元素
方法一:通过索引切换到框架
索引是帧处理的属性之一 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 of the element");
通过ID切换到iframe示例:
通过 Web 元素添加到框架
我们可以通过以下 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。
方法三:通过 Web Element 切换到框架
我们甚至可以使用 Web 元素切换到 iframe。
driver.switchTo().frame(WebElement);
如何切换回主框架
我们必须退出 iframe。
要返回到父框架,您可以使用 switchTo().parentFrame(),或者如果您想返回到主(或最父)框架,您可以使用 switchTo().defaultContent();
driver.switchTo().parentFrame(); driver.switchTo().defaultContent();
如果我们不能使用 ID 或 Web 元素进行切换,如何切换框架:
假设页面中有 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();}
上面的“forloop”迭代页面中的所有 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 中找到 1st处,则索引为 0。
- 如果你发现 1 人中有 3 人rd 位,指数为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 的 Index 或 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(); } }
输出:
上述代码的输出将打印内框和外框中的文本。