Skip to content

网页 frames 与多窗口处理


简介

要定位一个元素时,怎么都定位不到的时候就要考虑是不是浏览器内嵌了一个 frame 窗口或者要找的元素在新打开的窗口里。这时候就需要进行 frame 的切换或者窗口的切换。


iframe 解析


iframe 的多种切换方式

<iframe src="1.html" id="hogwarts_id" name="hogwarts_name"></iframe>
# index:传入整型的参数,从 0 开始,这里的 0 就是第一个 frame
driver.switch_to.frame(0)

#id:iframe 的 id
driver.switch_to.frame("hogwarts_id")

#name: iframe 的 name
driver.switch_to.frame("hogwarts_name")

#WebElement: 传入 `selenium.webelement` 对象
driver.switch_to.frame(driver.find_element(By.TAG_NAME,"iframe"))

iframe 切换回默认页面

在切换页面之后,如果还想操作原页面,则可以使用:

# python
driver.switch_to.default_content()
# java
driver.switchTo().defaultContent();

iframe 多层切换

driver.switch_to.frame("iframe1")
driver.switch_to.frame("iframe2")

从 iframe2 切换回 iframe1 可以使用父子切换:

# 从 iframe2 切换到上一级 iframe1
driver.switch_to.parent_frame()
# 从 iframe1 切换到上一级 iframe,如果 iframe 已经是最上级,则保持不变
driver.switch_to.parent_frame()

多窗口处理

元素有属性,浏览器的窗口其实也有属性的,浏览器窗口的属性用句柄(handle)来识别。 当浏览器打开一个窗口时,如果要在新的窗口操作就需要句柄切换。


句柄的获取

driver = webdriver.Chrome()
handles = driver.window_handles
print(handles)
['CDwindow-8012E9EF4DC788A58DC1588E7B8A7C44', 'CDwindow-11D52927C71E7C2B9984F2D1E2856049']

句柄的切换

from selenium import webdriver

driver = webdriver.Chrome()
handles = driver.window_handles
print(handles)
driver.switch_to.window(handles[-1])

实战演示(Python)

必应搜索“霍格沃兹测试开发”,点击“霍格沃兹测试开发学社”。


from selenium import webdriver


class TestHogwartsDemo:
    def setup_method(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(5)

    def teardown_method(self):
        self.driver.quit()

    def test_switch_window(self):
        # 进入必应搜索
        self.driver.get("https://cn.bing.com/")
        # 输入关键词
        self.driver.find_element(By.CSS_SELECTOR, "#sb_form_q").send_keys("霍格沃兹测试开发")
        # 点击搜索按钮
        self.driver.find_element(By.CSS_SELECTOR, "#search_icon").click()
        # 点击霍格沃兹测试开发学社官网
        self.driver.find_element(By.XPATH,
                                 "//*[@class='b_algo']//*[contains(text(),'测试开发训练营 大厂私教职场守护')]/../../h2/a").click()
        # 将获取到的 window_handles 赋值给一个变量 handles
        handles = self.driver.window_handles
        # 切换句柄
        self.driver.switch_to.window(handles[-1])
        assert len(self.driver.find_elements(By.CSS_SELECTOR, '.navbar-brand')) == 1

实战演示(Java)

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;

public class demoTest {
    static WebDriver driver;
    @AfterAll
    static void teardown(){
        driver.quit();
    }
    @BeforeAll
    static void setup(){
        driver = new EdgeDriver();
    }


    @Test
    void demo(){

       # 进入必应搜索
        driver.get("https://cn.bing.com/")
        # 输入关键词
        driver.findElement(By.CSS_SELECTOR, "#sb_form_q").send_keys("霍格沃兹测试开发")
        # 点击搜索按钮
        driver.find_element(By.cssSelector( "#search_icon")).click()
        # 点击霍格沃兹测试开发学社官网
        driver.findElement(By.xpath(
                                 "//*[@class='b_algo']//*[contains(text(),'测试开发训练营 大厂私教职场守护')]/../../h2/a")).click()
        # 将获取到的 window_handles 赋值给一个变量 handles
        handles = driver.getWindowHandles();
        # 切换句柄
        driver.switchTo().window(handles[-1])
        assert len(self.driver.findElements(By.cssSelector( '.navbar-brand'))) == 1
    }
}

总结

  • frame
  • window_handle