Python 测开28期 - WL - 学习笔记 - frame与文件上传处理

网页 frame 与多窗口处理

  • selenium 里边如何处理多窗口场景
    • 多个窗口识别
    • 多个窗口之间切换
  • selenium 里边如何处理 frame
  • 多个 frame 识别
  • 多个 frame 之间切换

多窗口处理

  • 点击某些链接,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了
  • 获取窗口的唯一标识用句柄表示,所以只需要切换句柄,就可以在多个页面灵活操作了

多窗口处理流程

    1. 先获取到当前的窗口句柄(driver.current_window_handle)
    1. 再获取到所有的窗口句柄(driver.window_handles)
    1. 判断是否是想要操作的窗口,如果是,就可以对窗口进行操作,如果不是,跳转到另一个窗口,对另一个窗口进行操作(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(“文件路径 + 文件名”)

文件上传实例

  • 打开百度图片网址:https://image.baidu.com
  • 识别上传按钮
  • 点击上传按钮
  • 将本地的图片文件上传
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)