web自动化-iFrames和窗口

发布时间 2023-07-27 00:25:42作者: 琉璃星眸

框架中元素的定位和选择方法:

 

我们使⽤浏览器开发⼯具检查元素,我们可能会看到以下内容
<div id="modal">
 <iframe
id="buttonframe"name="myframe"src="https://seleniumhq.github.io">
 <button>Click here</button>
 </iframe>
</div>
如果不是 iframe,我们可能会使⽤如下⽅式点击按钮:
driver.find_element(By.TAG_NAME, 'button').click()
但是,可能会得到⼀个 no such element ⽆此元素 的错误。 这是因为 Selenium 只知道顶层⽂档中的元素。为了与按钮进⾏交互,我们需要⾸先切换到框架, 这与切换窗⼜的⽅式类似。WebDriver 提供了三种切换到帧的⽅法
 
使⽤ WebElement
使⽤ WebElement 进⾏切换是最灵活的选择。您可以使⽤⾸选的选择器找到框架并切换到它。
 # 存储⽹⻚元素
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")
 # 切换到选择的 iframe
driver.switch_to.frame(iframe)
 # 单击按钮
driver.find_element(By.TAG_NAME, 'button').click()
使⽤ name 或 id
如果您的 frame 或 iframe 具有 id 或 name 属性,则可以使⽤该属性。如果名称或 id 在页
⾯上不是唯⼀的, 那么将切换到找到的第⼀个。
 # 通过 id 切换框架
driver.switch_to.frame('buttonframe')
 # 单击按钮
driver.find_element(By.TAG_NAME, 'button').click()
使⽤索引
还可以使⽤frame的索引, 例如可以使⽤JavaScript中的 window.frames 进⾏查询.
# 基于索引切换到第 1 个 iframe,从0开始
driver.switch_to.frame(0)
# 单击按钮
driver.find_element(By.LINK_TEXT, 'Click me').click()
## 离开框架
离开 iframe 或 frameset,切换回默认内容,如下所示:
 # 切回到默认内容
driver.switch_to.default_content()
 
四、同窗⼜和标签⼀起⼯作
 
窗⼜和标签页
WebDriver 没有区分窗⼜和标签页。如果你的站点打开了⼀个新标签页或窗⼜,Selenium将允许您使⽤窗⼜句柄来处理它。 每个窗⼜都有⼀个唯⼀的标识符,该标识符在单个会话中保持持久性。你可以使⽤以下⽅法获得当前窗⼜的窗⼜句柄:
driver.current_window_handle
切换窗⼜或标签页
 
单击在 <a href=“https://seleniumhq.github.io"target="_blank”>新窗⼜ 中打开链接, 则屏幕会聚焦在新窗⼜或新标签页上,但 WebDriver 不知道操作系统认为哪个窗⼜是活动的。要使⽤新窗⼜,您需要切换到它。 如果只有两个选项卡或窗⼜被打开,并且你知道从哪个窗⼜开始, 则你可以遍历 WebDriver, 通过排除法可以看到两个窗⼜或选项卡,然后切换到你需要的窗⼜或选项卡。不过,Selenium 4 提供了⼀个新的 api NewWindow 它创建⼀个新选项卡 (或) 新窗⼜并⾃动切换到它
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 # 启动驱动程序
with webdriver.Firefox() as driver:
 # 打开⽹址
driver.get("https://seleniumhq.github.io")
 # 设置等待
 wait = WebDriverWait(driver, 10)
 # 存储原始窗⼝的 ID
 original_window = driver.current_window_handle
 # 检查⼀下,我们还没有打开其他的窗⼝
 assert len(driver.window_handles) == 1
 # 单击在新窗⼝中打开的链接
 driver.find_element(By.LINK_TEXT, "new window").click()
 # 等待新窗⼝或标签⻚
 wait.until(EC.number_of_windows_to_be(2))
 # 循环执⾏,直到找到⼀个新的窗⼝句柄
 for window_handle in driver.window_handles:
  if window_handle != original_window:
   driver.switch_to.window(window_handle)
   break
 # 等待新标签⻚完成加载内容
 wait.until(EC.title_is("SeleniumHQ Browser Automation"))

创建新窗⼜(或)新标签页并且切换
 
创建⼀个新窗⼜ (或) 标签页,屏幕焦点将聚焦在新窗⼜或标签在上。您不需要切换到新窗⼜ (或) 标签页。如果除了新窗⼜之外, 您打开了两个以上的窗⼜ (或) 标签页,您可以通过遍历 WebDriver 看到两个窗⼜或选项卡,并切换到⾮原始窗⼜。注意: 该特性适⽤于 Selenium 4 及其后续版本。
 # 打开新标签⻚并切换到新标签⻚
driver.switch_to.new_window('tab')
 # 打开⼀个新窗⼝并切换到新窗⼝
driver.switch_to.new_window('window')
关闭窗⼜或标签页
当你完成了⼀个窗⼜或标签页的⼯作时,并且它不是浏览器中最后⼀个打开的窗⼜或标签页时,你应该关闭它并切换回你之前使⽤的窗⼜。 假设您遵循了前⼀节中的代码⽰例,您将把前⼀个窗⼜句柄存储在⼀个变量中。把这些放在⼀起,你会得到:
 #关闭标签⻚或窗⼝
driver.close()
 #切回到之前的标签⻚或窗⼝
driver.switch_to.window(original_window)
如果在关闭⼀个窗口后忘记切换回另⼀个窗口句柄,WebDriver 将在当前关闭的页⾯上执⾏,并触发⼀个 No Such Window Exception ⽆此窗口异常。必须切换回有效的窗口句柄才能继续执⾏。
 
在会话结束时退出浏览器
当你完成了浏览器会话,你应该调⽤ quit 退出,⽽不是 close 关闭(close 只会关闭⼀个页签或窗口):
driver.quit()
退出将会
关闭所有与 WebDriver 会话相关的窗⼜和选项卡
结束浏览器进程
结束后台驱动进程
通知 Selenium Grid 浏览器不再使⽤,以便可以由另⼀个会话使⽤它(如
果您正在使⽤ Selenium Grid)
调⽤ quit() 失败将留下额外的后台进程和端⼜运⾏在机器上,这可能在以后导致⼀些问题。
有的测试框架提供了⼀些⽅法和注释,您可以在测试结束时放⼊teardown() ⽅法中
# unittest teardown
# https://docs.python.org/3/library/unittest.html?
highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
 self.driver.quit()
Python 的 WebDriver 现在⽀持 Python 上下⽂管理器,当使⽤ with 关键字时,可以在执⾏结束时⾃动退出驱动程序。
with webdriver.Firefox() as driver:
   # WebDriver 代码…
# 在此缩进位置后 WebDriver 会⾃动退出