网页 frame 与多窗口处理
- selenium 里边如何处理多窗口场景
- selenium 里边如何处理 frame
- 多个 frame 识别
- 多个 frame 之间切换
多窗口处理
- 点击某些链接,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了
- 获取窗口的唯一标识用句柄表示,所以只需要切换句柄,就可以在多个页面灵活操作了
多窗口处理流程
-
- 先获取到当前的窗口句柄(driver.current_window_handle)
-
- 再获取到所有的窗口句柄(driver.window_handles)
-
- 判断是否是想要操作的窗口,如果是,就可以对窗口进行操作,如果不是,跳转到另一个窗口,对另一个窗口进行操作(driver.switch_to_window)
多窗口切换案例
- 打开百度页面
- 点击登录
- 弹框中点击‘立即注册’,输入用户名和账号
- 返回刚才的登录页,点击登录
- 输入用户名和密码,点击登录
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from web_Driver.web_lv2.base import Base
class TestWindows(Base):
def test_windows(self):
self.driver.get('https://baidu.com')
self.driver.find_element(By.CSS_SELECTOR, '.s-top-login-btn.c-btn.c-btn-primary.c-btn-mini.lb').click()
self.driver.find_element(By.CSS_SELECTOR, '.pass-reglink.pass-link').click()
windows = self.driver.window_handles
self.driver.switch_to.window(windows[-1])
self.driver.find_element(By.XPATH, '//*[@id="TANGRAM__PSP_4__userName"]').send_keys('newuser')
self.driver.find_element(By.XPATH, '//*[@id="TANGRAM__PSP_4__password"]').send_keys('a132456789')
self.driver.find_element(By.XPATH, '//*[@id="TANGRAM__PSP_4__submit"]').click()
self.driver.find_element(By.XPATH, '//*[text()="《百度用户协议》"]').click()
windows = self.driver.window_handles
self.driver.switch_to.window(windows[-1])
ele = self.driver.find_element(By.CSS_SELECTOR, '.grid-96 > a')
ActionChains(self.driver).scroll_to_element(ele).perform()
frame 介绍
- 在 web 自动化中,如果一个元素定位不到,呢么很大可能是在 iframe 中
- 什么是 frame?
- frame 是 html 中的框架,在 html 中, 所谓的框架就是可以在同一个浏览器显示不止一个页面
- 基于 html 的框架,又分为垂直框架和水平框架(cols, rows)
- frame 分类
- frame 标签包含 frameset、frame、iframe 三种
- frameset 和普通的标签一样,不会影响正常的定位,可以使用 index、id、name、webelement 任意种方式定位 frame
- 而 frame 与 iframe 对 selenium 定位而言是一样的,selenium有一组方法对 frame 进行操作
- 演示:https://www/w3school.com.cn/tiy/t.asp?f=html_frame_cols
多 frame 切换
- frame 存在两种
- 切换 frame
- driver.switch_to.frame(index):根据元素 id 或者 index 切换 frame
- drriver.switch_to.default_content():切换到默认 frame
- driver.switch_to.parent_frame():切换到父级 frame
frame 未嵌套
- 处理未嵌套的 iframe
- driver.switch_to_frame(“frame 的 id”)
- driver.switch_to_frame(“frame - index”) frame 无 ID的时候依据索引来处理,索引从0开始,driver.switch_to_frame(0)
frame 嵌套
- 处理嵌套的 iframe
- 对于嵌套的先进入到 iframe 的父节点,在进到子节点,然后可以对子节点里面的对象进行处理和操作
- driver.switch_to.frame(“父节点”)
- driver.switch_to.frame(“子节点”)
- driver.switch_to.parent_frame():自动切换回父节点
- driver.switch_to.default_content():切换窗口都默认的窗口
多 frame 切换案例
- 打开包含 frame 的web页面:菜鸟教程在线编辑器
- 打印‘请拖拽我’元素的文本、
- 打印‘点击运行’元素的文本
def test_frame(self):
self.driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
self.driver.switch_to.frame('iframeResult')
ele =self.driver.find_element(By.ID, 'draggable')
print(f'ele= {ele.text}')
# 自动切换回父级节点
self.driver.switch_to.parent_frame()
eles = self.driver.find_element(By.ID, 'submitBTN')
print(f'eles={eles}')
文件上传、弹窗处理
文件上传
- input 标签可以直接使用 send_keys(文件地址) 上传文件
- 用法
- el = driver.find_element_by_id(“上传按钮 id”)
- el.send_keys(“文件路径 + 文件名”)
文件上传实例
def test_file_unload(self):
self.driver.get('https://image.baidu.com')
self.driver.find_element(By.XPATH, '//*[@id="sttb"]/img[1]').click()
self.driver.find_element(By.ID,'stfile').send_keys("D:\\testuser\\web_Driver\\web_lv2\\image\\testhetong51.jpg")
time.sleep(5)
弹框处理机制
- 在页面操作中有时会遇到JavaScript所生成的alert、confirm以及prompt弹框,可以使用switch_to.alert0方法定位到。然后使用text/accept/dismiss/send keys等方法进行操作。参考教你分alert、window、div模态框,以及操作
- 操作alert常用的方法:
- switch_to.alert0):获取当前页面上的警告框
- text:返回alert/confirm/prompt 中的文字信息
- accept():接受现有警告框。
- dismiss():解散现有警告框
- send_keys(keysToSend): 发送文本至警告框。keysToSend:将文本发送至警告框
alert 窗口处理案例
def test_alert(self):
self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
self.driver.switch_to.frame('iframeResult')
left = self.driver.find_element(By.ID, 'draggable')
right = self.driver.find_element(By.ID, 'droppable')
ActionChains(self.driver).drag_and_drop(left, right).perform()
time.sleep(3)
# 切换到 alert 弹窗并迪纳基确认
self.driver.switch_to.alert.accept()
# 切换窗口都默认的窗口
self.driver.switch_to.default_content()
self.driver.find_element(By.ID, 'submitBTN').click()
time.sleep(3)