测试老宅男扶摇

导航

Selenium4Web自动化5-iframe与窗口等控件切换

一、浏览器导航

打开网站

启动浏览器后你要做的第一件事就是打开你的网站。这可以通过一行代码实现

driver.get("http://wwww.baidu.com/")

后退

按下浏览器的后退按钮

driver.back()

前进

按下浏览器的前进键

driver.forward()

刷新

刷新当前页面

driver.refresh()

二、JavaScript 警告框,提示框和确认框

WebDriver提供了一个API, 用于处理JavaScript提供的三种类型的原生弹窗消息. 这些弹窗由浏览器提供限定的样式.

Alerts 警告框

其中最基本的称为警告框, 它显示一条自定义消息, 以及一个用于关闭该警告的按钮, 在大多数浏览器中标记为"确定"(OK). 在大多数浏览器中, 也可以通过按"关闭"(close)按钮将其关闭, 但这始终与“确定”按钮具有相同的作用.
WebDriver可以从弹窗获取文本并接受或关闭这些警告

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See an example alert").click()

# Wait for the alert to be displayed and store it in a variable
alert = wait.until(expected_conditions.alert_is_present())

# Store the alert text in a variable
text = alert.text

# Press the OK button
alert.accept()

Confirm 确认框

确认框类似于警告框, 不同之处在于用户还可以选择取消消息. 查看样例确认框.
此示例还呈现了警告的另一种实现:

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample confirm").click()

# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())

# Store the alert in a variable for reuse
alert = driver.switch_to.alert

# Store the alert text in a variable
text = alert.text

# Press the Cancel button
alert.dismiss()

Prompt 提示框

提示框与确认框相似, 不同之处在于它们还包括文本输入. 与处理表单元素类似, 您可以使用WebDriver的sendKeys来填写响应. 这将完全替换占位符文本. 按下取消按钮将不会提交任何文本.

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample prompt").click()

# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())

# Store the alert in a variable for reuse
alert = Alert(driver)

# Type your message
alert.send_keys("Selenium")

# Press the OK button
alert.accept()

PS:Chrome浏览器,在send_keys这个操作上存在问题,在国外知名男性交友网站stackoverflow上,我找到了答案:首先火狐不存在该问题,然后谷歌,就是一个显示的问题,不会在文本框中显示输入的文本,实际会在点击确认警告框后,提交发送的文本信息

问题链接:
https://stackoverflow.com/questions/53567385/selenium-alert-sendkeys-with-chrome-is-not-working

三、同cookies一起工作

Cookie是从网站发送并存储在您的计算机中的一小段数据. Cookies主要用于识别用户并加载存储的信息.
WebDriver API提供了一种使用内置的方法与Cookie进行交互

这个方法常常用于将cookie添加到当前访问的上下文中. 添加Cookie仅接受一组已定义的可序列化JSON对象. 这里 是一个链接, 用于描述可接受的JSON键值的列表
首先, 您需要位于有效Cookie的域上. 如果您在开始与网站进行交互之前尝试预设cookie, 并且您的首页很大或需要一段时间才能加载完毕, 则可以选择在网站上找到一个较小的页面 (通常404页很小, 例如 http://example.com/some404page)

from selenium import webdriver

driver = webdriver.Chrome()

driver.get("http://www.example.com")

# Adds the cookie into current browser context
driver.add_cookie({"name": "key", "value": "value"})

四、与iFrames和frames一起工作

框架是一种现在已被弃用的方法,用于从同一域中的多个文档构建站点布局。除非你使用的是 HTML5 之前的 webapp,否则你不太可能与他们合作。内嵌框架允许插入来自完全不同领域的文档,并且仍然经常使用。
如果您需要使用框架或 iframe, WebDriver 允许您以相同的方式使用它们。考虑 iframe 中的一个按钮。 如果我们使用浏览器开发工具检查元素,我们可能会看到以下内容

<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()

但是,如果 iframe 之外没有按钮,那么您可能会得到一个 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()

如果不在测试上下文中运行 WebDriver,您可以考虑使用 try / finally,这是大多数语言都提供的, 这样一个异常处理仍然可以清理 WebDriver 会话。

try:
    #WebDriver 代码…
finally:
driver.quit()

Python 的 WebDriver 现在支持 Python 上下文管理器,当使用 with 关键字时,可以在执行结束时自动退出驱动程序。
with webdriver.Firefox() as driver:

  # WebDriver 代码…

# 在此缩进位置后 WebDriver 会自动退出

窗口管理

屏幕分辨率会影响 web 应用程序的呈现方式,因此 WebDriver 提供了移动和调整浏览器窗口大小的机制。

获取窗口大小

获取浏览器窗口的大小(以像素为单位)。

    # 分别获取每个尺寸
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # 或者存储尺寸并在以后查询它们
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")

设置窗口大小

恢复窗口并设置窗口大小。

driver.set_window_size(1024, 768)

得到窗口的位置

获取浏览器窗口左上角的坐标。

    # 分别获取每个尺寸
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # 或者存储尺寸并在以后查询它们
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')

设置窗口位置

将窗口移动到设定的位置。

    # 将窗口移动到主显示器的左上角
driver.set_window_position(0, 0)

最大化窗口

扩大窗口。对于大多数操作系统,窗口将填满屏幕,而不会阻挡操作系统自己的菜单和工具栏。

driver.maximize_window()

最小化窗口

最小化当前浏览上下文的窗口. 这种命令的精准行为将作用于各个特定的窗口管理器.
最小化窗口通常将窗口隐藏在系统托盘中.
注意: 此功能适用于Selenium 4以及更高版本.

driver.minimize_window()

全屏窗口

填充整个屏幕,类似于在大多数浏览器中按下 F11。

driver.fullscreen_window()

屏幕截图

用于捕获当前浏览上下文的屏幕截图. WebDriver端点 屏幕截图 返回以Base64格式编码的屏幕截图.

from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()

元素屏幕截图

用于捕获当前浏览上下文的元素的屏幕截图. WebDriver端点 屏幕截图 返回以Base64格式编码的屏幕截图.

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()

执行脚本

在当前frame或者窗口的上下文中,执行JavaScript代码片段.

    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)

打印页面

打印当前浏览器内的页面
注意: 此功能需要无头模式下的Chromium浏览器

from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)

posted on 2022-10-24 14:25  测试老宅男扶摇  阅读(284)  评论(0编辑  收藏  举报