• Python —— UI自动化之 三大等待与三大切换


    1、三大等待

    1、硬性等待

    1、概述

    硬性等待也可以称之为强制等待,写法如下:

    time.sleep()

    优点:使用简单

    缺点:等待时间把握不准,容易造成时间浪费或者等待时间不足

    2、实战
    1. from time import sleep
    2. from selenium.webdriver.support import expected_conditions as EC
    3. from selenium import webdriver
    4. from selenium.webdriver.common.by import By
    5. from selenium.webdriver.support.wait import WebDriverWait
    6. driver = webdriver.Firefox()
    7. driver.get("http://mall.hahahah.com:VVVV/")
    8. driver.maximize_window()
    9. '''
    10. 第一类等待:强制等待
    11. '''
    12. sleep(5)
    13. driver.find_element(By.XPATH,"//div[text()='小熊摊手']").click()

    2、隐式等待

    1、概述

    在设置的超时时间范围内不断查找元素,直到找到元素或者超时为止,设置方式如下:

    driver.implicitly_wait(5)

    优点:全局应用,它适用于WebDriver会话期间中所有查找的Web元素(通过findElement方法) 缺点:只能等待元素存在,不能适用条件更复杂的情况,如:元素可点击、元素可见

    其他特点:

            1、如果超过隐式等待的设置时间还是找不到元素,就会抛出了NoSuchElementException-找不到元素异常

            2、放置的位置,一般我们会将其放置到driver的初始化之后

            3、全局生效,只需要设置一次,之后通过find_element去找元素都会有隐式等待的效果

            4、等待条件的区别,只能等待元素存在

    2、实战
    1. driver = webdriver.Firefox()
    2. driver.get("http://mall.lemonban.com:3344/")
    3. driver.maximize_window()
    4. '''第二类:隐式等待'''
    5. driver.implicitly_wait(5)
    6. driver.find_element(By.XPATH,"//div[text()='小熊摊手']").click()

    3、显式等待

    1、概述

    在设置的超时时间范围内根据特定条件不断查找元素,直到找到元素为止。(如元素存在、元素可点 击、元素可见等) 使用方式:

    1. from selenium.webdriver.support import expected_conditions as EC
    2. WebDriverWait(driver, 20,0.5).until(EC.presence_of_element_located((By.LINK_TEXT, '好123')))

    优点:可以设置更加丰富的特定条件

    缺点:仅对指定的元素生效,代码略复杂

    等待条件解释
    presence_of_element_located页面元素在页面源代码中存在
    visibility_of_element_located页面元素在页面存在并且可见
    element_to_be_clickable页面元素是否在页面上可被单击

    其他:

            1、如果超过显式等待的设置时间还是找不到元素,就会抛出了TimeoutException-超时异常            2、局部生效的,只能针对单个元素生效

            3、设置的时候是针对单个元素的,并不是全局的

            4、等待更多丰富的条件:等待元素可见、可被点击、等待元素存在...    

    2、实战
    1. driver = webdriver.Firefox()
    2. driver.get("http://mall.lemonban.com:3344/")
    3. driver.maximize_window()
    4. driver.find_element(By.XPATH,"//div[text()='小熊摊手']").click()
    5. # sleep(2)
    6. '''第三类:显示等待,driver,5,0.5 是5秒钟内每0.5s轮循一次'''
    7. WebDriverWait(driver,5,0.5).until(EC.element_to_be_clickable((By.CLASS_NAME,"buy-now"))).click()

    注意:EC.element_to_be_clickable()函数中的参数是元组形式哦,因此是这样的EC.element_to_be_clickable((By.XPATH, "//a[text()='ceshi']"))这样子

    2、三大切换

    1、切换Iframe-内联框架-内嵌的网页

    1、概述

    当想要定位iframe中的元素时,由于driver的焦点还停留在原页面,我们在iframe新的页面上定位元素 时,自然会产生错误,所以我们需要将driver的焦点切换到iframe页面中。

    切换方式:

    driver.switch_to.frame(XXX);
    

    跳转到父级iframe中:

    driver.switch_to.parent_frame(XXX);
    

    回到默认内容页面:

    driver.switch_to.default_content(XXX)
    2、实战
    1. from time import sleep
    2. from selenium import webdriver
    3. from selenium.webdriver.common.by import By
    4. driver = webdriver.Firefox()
    5. # driver.get("https://qzone.qq.com/")
    6. # driver.get("https://www.126.com/")
    7. # 切换iframe
    8. '''QQ空间案例'''
    9. # driver.switch_to.frame(driver.find_element(By.XPATH,"//iframe[@id='login_frame']"))
    10. # # sleep(2)
    11. # driver.find_element(By.ID,'switcher_plogin').click()
    12. # driver.find_element(By.ID,'u').send_keys('1425301899')
    13. # driver.find_element(By.ID,'p').send_keys('123456')
    14. # driver.find_element(By.ID,'login_button').click()
    15. # sleep(2)
    16. # # 返回上一个页面,即跳出当前的iframe
    17. # driver.switch_to.default_content()
    18. '''
    19. selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="u"]
    20. 会报错,因为有iframe
    21. driver.find_element(By.ID,'u')
    22. '''
    23. '''126邮箱案例 '''
    24. # 切换
    25. # driver.switch_to.frame(driver.find_element(By.XPATH,"//iframe[contains(@id,'x-URS-iframe')] "))
    26. # driver.find_element(By.XPATH,"//input[@placeholder='邮箱账号或手机号码']").send_keys("123456")
    27. # driver.find_element(By.NAME,"password").send_keys("123456")
    28. # driver.find_element(By.ID,"dologin").click()
    29. # sleep(6)
    30. # # 返回默认iframe页面
    31. # driver.switch_to.default_content()
    32. # driver.close()
    33. '''多层iframe嵌套的案例'''
    34. driver.get("file:///D:/%E6%9F%A0%E6%AA%AC%E7%8F%AD%E8%AF%BE%E7%A8%8B/web%E8%87%AA%E5%8A%A8%E5%8C%96/lemon/Python%E8%87%AA%E5%8A%A8%E5%8C%96VIP%E5%BD%95%E6%92%AD%E8%A7%86%E9%A2%91/py%E5%85%A8%E6%A0%8864%E6%9C%9F/%E5%8A%A0%E5%AF%86%E5%90%8E%E8%A7%86%E9%A2%91/iframe%E5%A4%9A%E5%B1%82%E5%B5%8C%E5%A5%97/a.html")
    35. driver.maximize_window()
    36. driver.find_element(By.ID,"aa").send_keys("hhh")
    37. sleep(3)
    38. # 切换到第一层iframe
    39. driver.switch_to.frame(driver.find_element(By.ID,"bframe"))
    40. driver.find_element(By.ID,"bb").send_keys("你好,今天和明天")
    41. sleep(5)
    42. # 切换到第二层iframe
    43. driver.switch_to.frame(driver.find_element(By.ID,"cframe"))
    44. driver.find_element(By.ID,"cc").send_keys("人生美好")
    45. sleep(2)
    46. # 回到默认页面
    47. # 方法一
    48. driver.switch_to.default_content()
    49. # 方法二
    50. driver.switch_to.parent_frame()
    51. driver.switch_to.parent_frame()
    52. # 清楚原来写入输入框的元素
    53. driver.find_element(By.ID,"aa").clear()
    54. driver.close()

    2、弹窗切换

    1、概述

    弹窗有三种不同类型:

            alert(警告消息框)、

            confirm(确认消息框)、

            prompt(提示消息对话框) 通过switch_to.alert()切换到弹窗,再使用accept、dismiss、send_keys、text方法进行操作

    2、实战
    1. from time import sleep
    2. from selenium import webdriver
    3. from selenium.webdriver.common.by import By
    4. ''' 弹窗切换 '''
    5. driver = webdriver.Firefox()
    6. driver.get("file:///D:/%E6%9F%A0%E6%AA%AC%E7%8F%AD%E8%AF%BE%E7%A8%8B/web%E8%87%AA%E5%8A%A8%E5%8C%96/lemon/Python%E8%87%AA%E5%8A%A8%E5%8C%96VIP%E5%BD%95%E6%92%AD%E8%A7%86%E9%A2%91/py%E5%85%A8%E6%A0%8864%E6%9C%9F/%E5%8A%A0%E5%AF%86%E5%90%8E%E8%A7%86%E9%A2%91/%E5%BC%B9%E7%AA%97%E4%B8%8B%E6%8B%89%E6%A1%86demo.html")
    7. driver.maximize_window()
    8. sleep(2)
    9. '''1、警告窗,比较常见,不需要切换'''
    10. # driver.find_element(By.ID,"alert").click()
    11. # sleep(5)
    12. '''2、确认窗'''
    13. # 点击确认框
    14. # driver.find_element(By.ID,'confirm').click()
    15. # sleep(2)
    16. # 切换弹窗
    17. # driver.switch_to.alert.accept() 确认
    18. # print(driver.switch_to.alert.text) 输出:confirm弹窗演示
    19. # driver.switch_to.alert.dismiss() 取消
    20. '''3、提示窗,比较少见'''
    21. driver.find_element(By.ID,"prompt").click()
    22. sleep(2)
    23. driver.switch_to.alert.send_keys("测试测试测试")
    24. sleep(3)
    25. driver.close()

    3、切换windows

    1、概述

    当我们点击了 a 标签元素(超链接)时,会触发打开链接页面的事件,有两种情形:

             1. 在当前窗口加载新页面内容

            2. 新建一个窗口加载新页面内容,这种情况在 a 标签有 target="_blank" 时触发

    当发生第2种情况时,同iframe类似,我们需要切换窗口 切换方式: 传入要操作窗口的handle句柄 --窗口的标识,唯一

    driver.switch_to.window()
    

     如何获取到窗口的句柄

    1. driver.current_window_handle(); #获取当前操作窗口的句柄
    2. driver.window_handles(); #获取所有打开的窗口句柄

    备注:窗口的句柄并不是固定的,而是由浏览器分配的

    2、实战
    1. from time import sleep
    2. from selenium import webdriver
    3. from selenium.webdriver.common.by import By
    4. driver = webdriver.Firefox()
    5. driver.get("https://www.baidu.com/")
    6. driver.maximize_window()
    7. #有一个问题,点击超链接时,超链接元素有属性target="_blank"就会重新打开一个页面
    8. print(driver.window_handles) # 输出:['b9ddb693-1b03-4e62-981f-f432e01cfe2d']
    9. driver.find_element(By.LINK_TEXT,"地图").click()
    10. driver.find_element(By.LINK_TEXT,"hao123").click()
    11. print(driver.window_handles) # 最开始打开的页面,有一个句柄,如果再打开2个,那么就会增加2个新的句柄
    12. '''
    13. 输出:
    14. ['d18c1856-8718-4ec8-9541-665d9605c402', '6a90cdf8-20c6-42e7-a55e-397ecf6e5fa6', '8f90fcc2-633b-4b77-9489-982d9e1a9c4b']
    15. '''
    16. handles = driver.window_handles
    17. # 切换窗口,可以根据下标或者用标题去切换
    18. driver.switch_to.window(handles[-1]) # 用下标
    19. #如果是同时打开了多个窗口,要去切换到目标窗口中
    20. for handle in handles:
    21. #判断是否符合目标窗口,通过url地址或者title确定
    22. if driver.title == 'hao123_上网从这里开始':
    23. # url地址
    24. # if driver.current_url == 'https://www.hao123.com/?src=from_pc':
    25. # 符合的话,就说明当前driver是在目标窗口里面,所以就退出循环
    26. break
    27. else:
    28. # 否则我们就需要切换窗口
    29. driver.switch_to.window(handle)
    30. driver.find_element(By.LINK_TEXT,'携程旅行网').click()
    31. #需要注意,窗口的句柄并不是固定的,而是由浏览器分配的,类似于进程号
    32. #窗口句柄是唯一,但是并不固定
    33. sleep(5)
    34. driver.close()

    3、扩展

    如果元素定位不到,有哪些原因?

    1、检查我们的元素定位表达式是否写错,可以F12搜索验证

    2、检查是否是需要加等待

    3、检查是否元素在iframe中,如果是的话就需要切换iframe

    4、检查元素是否在新的窗口中,如果是的话我们就需要切换窗口

  • 相关阅读:
    TCP/IP(十五)拥塞控制
    spark sql重分区
    2022阿里云栖大会,顶尖科技趋势峰会和全链路元宇宙体验
    区分前端HTML标签中的href和src
    接口测试vs功能测试
    二百零七、Flume——Flume实时采集5分钟频率的Kafka数据直接写入ODS层表的HDFS文件路径下
    ElasticSearch安装详细教程以及相关踩坑
    协议-TCP协议-基础概念01-TCP头格式-TCP连接状态图-三次握手和四次挥手
    kafka笔记(一):kafka概述及入门-基础框架/消息队列/安装部署/命令行操作
    用ST-LINK 出现连接失败【已解决】
  • 原文地址:https://blog.csdn.net/lzf_hlh/article/details/133799569