• Web自动化之Selenium常用操作


    本文总结使用selenium进行web/UI自动化时,会用到的一些常用操作。

    定位元素

    driver.find_element_by_xpath()#1、绝对路径 2、元素属性 3、层级和属性结合 4、使用逻辑运算符
    driver.find_element_by_id()#根据id定位,HTML规定id属性在HTML文档中必须是唯一的
    driver.find_element_by_name()#name属性定位
    driver.find_element_by_class_name()#class属性定位
    driver.find_element_by_tag_name()#标签名字定位 因为标签基本都不是唯一的,所以不用这个
    driver.find_element_by_link_text()#定位文本链接,需要对应的元素有href属性
    driver.find_element_by_partial_link_text()#模糊定位文本链接
    driver.find_element_by_css_selector()#CSS选择器

    By定位元素

    元素定位另外一种方式,跟上面的8种底层一样。

    from selenium.webdriver.common import By
    driver.find_element(By.ID,'kw')

    定位一组元素

    driver.find_elements_by_xpath()#其他方法同理
    
    driver.find_elements(By.XPATH,'') 

    浏览器操作

    driver.set_window_size()#设置浏览器大小,可以设置成移动端大小
    driver.back()#浏览器后退
    driver.forward()#浏览器前进
    driver.set_window_position()
    driver.set_window_rect()
    driver.refresh()#模拟浏览器刷新
    driver.maximize_window()#最大化浏览器
    

    设置浏览器参数

    在定义driver的时候设置chrome_options参数,该参数是一个Options类所实例化的对象。其中,常用的参数是设置浏览器是否可视化和浏览器的请求头等信息,前者可以加快代码的运行速度,后者可以有效地防止网站的反爬虫检测

    1. from selenium.webdriver.chrome.options import Options
    2. url='https://movie.douban.com/'
    3. #Options类实例化
    4. chrome_options=Options()
    5. #设置浏览器参数
    6. #--headless是不 显示浏览器启动和执行过程c
    7. chrome_options.add_argument('--headless')
    8. #设置lang和User-Agent信息,防止反爬虫检测
    9. chrome_options.add_argument('lang=zh_CN.UTF-8')
    10. UserAgent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.101 Safari/537.36'
    11. chrome_options.add_argument('User-Agent='+UserAgent)
    12. #启动浏览器并设置chrome_options参数
    13. driver=webdriver.Chrome(options=chrome_options)
    14. driver.get(url)
    15. driver.maximize_window()
    16. print(driver.title)
    17. # print(driver.page_source) #获取网页的html代码

    元素操作

    driver.find_element_by_xpath().click()#点击元素
    driver.find_element_by_xpath().clear()#清空文本
    driver.find_element_by_xpath().send_keys()#模拟键盘输入
    

     页面交互

    webElement接口提供了一些可以与页面交互的方法

    submit和click在某些情况下可以互换,submit只用于表单的提交按钮。

    driver.find_element_by_xpath().submit()#提交输入框的内容 类似于回车提交搜索框内容
    driver.find_element_by_xpath().size#返回元素尺寸
    driver.find_element_by_xpath().text#获取元素文本
    driver.find_element_by_xpath().get_attribute()#获取元素属性值
    driver.find_element_by_xpath().is_selected()#是否被选中
    driver.find_element_by_xpath().is_enabled()#判断元素是否可以使用
    driver.find_element_by_xpath().is_displayed()#返回元素是否用户可见

    鼠标事件

    关于鼠标操作的方法都封装在Actionchains中

    from selenium.webdriver.common.action_chains import ActionChains
    rigt_check=driver.find_element_by_id('kw')
    ActionChains(driver).context_click(rigt_check).perform()#context_click对元素右击操作
    #perform()执行所有ActionChains中存储的行为
    ActionChains(driver).move_to_element(rigt_check).perform()#鼠标悬停
    ActionChains(driver).double_click(rigt_check).perform()#鼠标双击
    ActionChains(driver).drag_and_drop(source,target).perform()#鼠标由源元素拖动至目标元素
    

    1. url='https://passport.bilibili.com/login'
    2. driver=webdriver.Chrome()
    3. driver.get(url)
    4. #双击登录按钮
    5. ele=driver.find_element_by_class_name('tit')
    6. ActionChains(driver).double_click(ele).perform()
    7. sleep(2)
    8. #拖拽滑块
    9. ele=driver.find_element_by_class_name('gt_slider_knob,gt_show')
    10. ActionChains(driver).drag_and_drop_by_offset(ele,100,0).perform()

    键盘事件

    模拟键盘输入,可以是按键,组合键。

    from selenium.webdriver.common.keys import Keys
    driver.find_element_by_xpath().send_keys(Keys.BACK_SPACE)#对该元素操作一次backspace
    driver.find_element_by_xpath().send_keys(Keys.SPACE)#对该元素输入空格
    driver.find_element_by_xpath().send_keys(Keys.CONTROL,'a')#ctrl+A全选输入框内容
    driver.find_element_by_xpath().send_keys(Keys.CONTROL,'x')#ctrl+x剪切输入框内容
    driver.find_element_by_xpath().send_keys(Keys.CONTROL,'v')#ctrl+v粘贴内容到输入框
    driver.find_element_by_xpath().send_keys(Keys.ENTER)#通过回车键代替单击操作
    driver.find_element_by_xpath().send_keys(Keys.F1)#键盘F1

    1. from selenium import webdriver
    2. from selenium.webdriver.common.action_chains import ActionChains
    3. from selenium.webdriver.common.keys import Keys
    4. from selenium.webdriver.common.by import By
    5. from time import sleep
    6. url='https://www.baidu.com'
    7. driver=webdriver.Chrome()
    8. driver.get(url)
    9. ele=driver.find_element_by_id('kw')
    10. ele.send_keys("selenium")
    11. sleep(2)
    12. #删除最后一个文字
    13. ele.send_keys(Keys.BACK_SPACE)
    14. sleep(2)
    15. #添加空格键+教程
    16. ele.send_keys(Keys.SPACE)
    17. ele.send_keys("教程")
    18. sleep(2)
    19. #ctrl+a全选输入框内容
    20. ele.send_keys(Keys.CONTROL,'a')
    21. sleep(2)
    22. #ctrl+x 剪切输入框内容
    23. ele.send_keys(Keys.CONTROL,'x')
    24. sleep(2)
    25. #ctrl+v 粘贴内容到输入框
    26. ele.send_keys(Keys.CONTROL,'v')
    27. sleep(2)
    28. #回车键代替单击
    29. driver.find_element_by_id('su').send_keys(Keys.ENTER)

    获得验证信息

    自动化用例执行完成后,可以从页面上获取一些信息来证明用例执行成功或者失败

    driver.title #获得页面title
    driver.current_url#获得页面curl
    driver.find_element_by_xpath().text#获取元素文本

     元素等待

    由于web页面多数使用AJAX技术,浏览器在加载页面时,页面上的元素可能不是同时被加载完成的,需要加入等待。

    显式等待:显性等待能够根据判断条件而灵活地等待,程序每隔一段时间检测一次,如果检测结果与条件相符,就执行下一步,否则继续等待,直到超过设置的最长时间为止

    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    element=WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located(By.ID,'kw'))
    #每0.5秒检测一次这个元素能否被定位到,5秒后超时
    #expected_conditions提供了很多预期条件判断方法
    #也可以用is_displayed()判断元素是否可见

    隐式等待

    隐性等待是指在一个设定的时间内检测网页是否加载完成,也就是一般情况下用户看到浏览器标签栏那个小圈不再转,才会执行下一步。比如代码中设置30秒等待时间,网页只要在30秒内完成加载就会自动执行下一步,如果超出30秒就会抛出异常。值得注意的是,隐性等待对整个driver的周期都起作用,所以只要设置一次即可。

    通过一定的时长等待页面上某元素加载完成,如果超出了设置的时长元素,还没有被加载,则抛出没有元素异常。

    通常设置在driver后面。

    driver.implicitly_wait(10)

    sleep休眠方法

    在需要的地方添加。

    from time import sleep
    sleep(3)
    

    隐性等待和显性等待相比于time.sleep这种强制等待更为灵活和智能,可解决各种网络延误的问题,隐性等待和显性等待可以同时使用,但最长的等待时间取决于两者之间的最大数,如上述代码的隐性等待时间为30秒,显性等待时间为20秒,则该代码的最长等待时间为隐性等待时间。 

    多框架切换

    frame是一个框架页面,在HTML 5中已经不支持使用框架,但在一些网站中依然会看到它的身影。frame的作用是在HTML代码中嵌套一个或多个不同的HTML代码,每嵌套一个HTML代码都需要由frame来实现

    iframe和frame实现的功能是相同的,只不过使用方式和灵活性有所不同,无论是iframe还是frame,Selenium的定位和操作方式都是一样的

    由于一个HTML可以嵌套一个或多个iframe,因此Selenium在操作不同的iframe时需要通过switch_to.frame()来切换到指定的iframe,再执行相应的操作 

    driver.switch_to.frame('kw')#可以直接取表单的id或者name属性,如果表单没有这两个属性,可以先定位表单元素,再切换
    driver.switch_to.parent_frame('kw')#跳出当前一级表单
    driver.switch_to.default_content('kw')#跳回最外层页面
    #根据索引定位
    driver.switch_to_frame(0)
    #根据id或者name属性
    driver.switch_to_frame('framea')
    新版本 driver.switch_to.frame(0)

    如百度知道的文本框 

    如下代码实现打开百度知道题目页面,点击我要回答,定位至iframe,输入内容,跳出iframe,并点击提交回答按钮

    1. url='https://zhidao.baidu.com/question/1903337615241287780.html'
    2. driver=webdriver.Chrome()
    3. driver.get(url)
    4. driver.maximize_window()
    5. #点击我要回答
    6. driver.find_element_by_id('answer-bar').click()
    7. #切换到frame内部的html
    8. driver.switch_to.frame('ueditor_0')
    9. #定位frame内部的元素
    10. driver.find_element_by_xpath('/html/body').send_keys('美国')
    11. #跳回网页HTML 如果不切回网页,则找不到提交回答按钮,且js代码也执行不了
    12. # driver.switch_to.default_content()
    13. js='window.scrollTo(0,100)'
    14. driver.execute_script(js)
    15. sleep(3)
    16. #点击网页提交回答按钮
    17. driver.find_element_by_xpath("//div[@class='addons line']/a").click()

     多窗口切换

    search_windows=driver.current_window_handle #获得当前窗口句柄
    
    all_handles=driver.window_handles #获得所有窗口的句柄
    driver.switch_to.window(handle)#切换窗口
    handles=driver.window_handles
    driver.switch_to_window(handles[0])
    driver.switch_to_window(handles[1])

    应用

    1. from selenium import webdriver
    2. from selenium.webdriver.common.by import By
    3. url='https://www.baidu.com/'
    4. driver=webdriver.Chrome()
    5. driver.get(url)
    6. driver.implicitly_wait(10)
    7. search_windows=driver.current_window_handle #获得窗口句柄
    8. driver.find_element_by_link_text('登录').click()
    9. driver.find_element_by_link_text('立即注册').click()
    10. import time
    11. #获得所有窗口的句柄
    12. all_handles=driver.window_handles
    13. #切换到注册窗口
    14. for handle in all_handles:
    15. if handle!=search_windows:
    16. driver.switch_to.window(handle)
    17. print("当前是注册窗口")
    18. time.sleep(2)
    19. #回到搜索窗口
    20. for handle in all_handles:
    21. if handle==search_windows:
    22. driver.switch_to.window(handle)
    23. print("当前是搜索窗口")
    24. driver.find_element_by_id('TANGRAM__PSP_4__closeBtn').click()#关闭注册窗口
    25. driver.find_element_by_id('kw').send_keys("selenium")
    26. driver.find_element_by_id('su').click()
    27. time.sleep(2)
    28. driver.quit()

    警告框处理

    webdriver中处理JavaScript生成的alert,confirm,prompt十分简单,具体做法是使用switch_to_alert方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/send_keys等方法进行操作。

    text:返回alert/confirm/prompt中的文字信息

    accept():接受现有警告框

    dismiss():解散现有警告框

    send_keys:发送文本至警告框

    应用,如图切换至alert并接受

    1. from selenium import webdriver
    2. from selenium.webdriver.common.action_chains import ActionChains
    3. from selenium.webdriver.common.by import By
    4. from time import sleep
    5. url='https://www.baidu.com/'
    6. driver=webdriver.Chrome()
    7. driver.get(url)
    8. driver.maximize_window()
    9. driver.implicitly_wait(10)
    10. #鼠标悬停至设置链接
    11. link=driver.find_element_by_id("s-usersetting-top")
    12. ActionChains(driver).move_to_element(link).perform()
    13. driver.find_element_by_link_text('搜索设置').click()
    14. #保存设置
    15. driver.find_element_by_class_name('prefpanelgo').click()
    16. sleep(2)
    17. #接受警告框
    18. # driver.switch_to_alert().accept()
    19. driver.quit()

     上传文件

    一般文件上传,是打开windows窗口从窗口中选择本地文件,但webdriver无法操作windows控件。

    1、普通上传 将本地文件路径作为值传给input标签,注意必须是input标签

    2、插件上传,基于flash,js,Ajax等技术实现上传

    #定位上传按钮,添加本地文件
    driver.find_element_by_name('file').send_keys("D:\\upload_file.txt")

    另一种方法为基于AutoIt软件来实现上传。但是不推荐,因为不在Python范围。

    下载文件

    webdriver允许设置默认的文件下载路径,文件会被自动下载并存放到设置的目录中

    操作cookie

    什么情况下回用到cookie操作?当开发人员开发一个功能,当用户登录后,会将用户的用户名写入浏览器cookie,指定key为username,就可以通过get_cookies()找到username,打印value。

    1. url='https://www.youdao.com/'
    2. driver=webdriver.Chrome()
    3. driver.get(url)
    4. driver.maximize_window()
    5. driver.implicitly_wait(10)
    6. # #获得cookie
    7. driver.add_cookie({'name':'Login_User','value':'Password'})
    8. cookie=driver.get_cookies()
    9. print("所有Cookie为",cookie)
    10. #获取name为Login_User的cookie
    11. one_cookie=driver.get_cookie('Login_User')
    12. print("Login_User的Cookie为",one_cookie)
    13. # "删除name为Login_User的cookie
    14. driver.delete_cookie('Login_User')
    15. surplus_cookies=driver.get_cookies()
    16. print("剩余的cookie为:",surplus_cookies)
    17. driver.delete_all_cookies()
    18. surplus_cookies=driver.get_cookies()
    19. print("剩余的cookie为:",surplus_cookies)
    20. driver.quit()

    返回结果为

    1. 所有Cookie为[{
    2. 'domain': 'www.youdao.com',
    3. 'httpOnly': False,
    4. 'name': '___rl__test__cookies',
    5. 'path': '/',
    6. 'secure': False,
    7. 'value': '1662293521877'
    8. }, {
    9. 'domain': '.youdao.com',
    10. 'expiry': 1696853521,
    11. 'httpOnly': False,
    12. 'name': 'OUTFOX_SEARCH_USER_ID',
    13. 'path': '/',
    14. 'secure': False,
    15. 'value': '"555592633@10.108.162.135"'
    16. }, {
    17. 'domain': 'www.youdao.com',
    18. 'httpOnly': False,
    19. 'name': 'Login_User',
    20. 'path': '/',
    21. 'secure': True,
    22. 'value': 'Password'
    23. }, {
    24. 'domain': '.youdao.com',
    25. 'expiry': 1696853520,
    26. 'httpOnly': False,
    27. 'name': 'OUTFOX_SEARCH_USER_ID_NCOO',
    28. 'path': '/',
    29. 'secure': False,
    30. 'value': '1883563674.2397'
    31. }]
    32. Login_User的Cookie为 {
    33. 'domain': 'www.youdao.com',
    34. 'httpOnly': False,
    35. 'name': 'Login_User',
    36. 'path': '/',
    37. 'secure': True,
    38. 'value': 'Password'
    39. }
    40. 剩余的cookie为: [{
    41. 'domain': 'www.youdao.com',
    42. 'httpOnly': False,
    43. 'name': '___rl__test__cookies',
    44. 'path': '/',
    45. 'secure': False,
    46. 'value': '1662293521877'
    47. }, {
    48. 'domain': '.youdao.com',
    49. 'expiry': 1696853521,
    50. 'httpOnly': False,
    51. 'name': 'OUTFOX_SEARCH_USER_ID',
    52. 'path': '/',
    53. 'secure': False,
    54. 'value': '"555592633@10.108.162.135"'
    55. }, {
    56. 'domain': '.youdao.com',
    57. 'expiry': 1696853520,
    58. 'httpOnly': False,
    59. 'name': 'OUTFOX_SEARCH_USER_ID_NCOO',
    60. 'path': '/',
    61. 'secure': False,
    62. 'value': '1883563674.2397'
    63. }]
    64. 剩余的cookie为: []

    调用Javascript

    可以用来控制浏览器滚动条

    1. url='https://www.baidu.com/'
    2. driver=webdriver.Chrome()
    3. driver.get(url)
    4. driver.find_element_by_id('kw').send_keys("selenium")
    5. driver.find_element_by_id('su').click()
    6. driver.set_window_size(600,600)
    7. #通过js设置浏览器窗口的滚动条位置
    8. js="window.scrollTo(500,500);"
    9. driver.execute_script(js)

     窗口截图

    1. url='https://www.baidu.com/'
    2. driver=webdriver.Chrome()
    3. driver.get(url)
    4. driver.find_element_by_id('kw').send_keys("selenium")
    5. driver.find_element_by_id('su').click()
    6. sleep(2)
    7. driver.get_screenshot_as_file("C:\\Users\\yangyl13\\Desktop\\3.png")
    8. driver.quit()

    关闭窗口

    driver.quit() #退出相关驱动程序,关闭所有窗口

    driver.close()#关闭单个窗口。

    验证码处理

    1、测试环境去掉验证码

    2、万能验证码

    3、验证码识别技术 如python-tesseract

    4、记录cookie

    下拉框选择

    from selenium.webdriver.support.select import Select
    Select(driver.find_element_by_id('')).select_by_index('2')#根据下拉框索引选择
    Select(driver.find_element_by_id('')).select_by_value('Python')#根据下拉框value属性选择
    Select(driver.find_element_by_id('')).select_by_visible_text('Python')#根据下拉框可见文本选择
    
  • 相关阅读:
    java毕业设计基于的企业办公管理系统设计与实现(附源码、数据库)
    STM32单片机酒精检测防酒驾系统酒精报警器
    网站有绕过认证逻辑漏洞怎么修复
    MP3项目前端创建(ui,框架,头文件)
    目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】目标视觉检测
    华为机试 - 模拟商场优惠打折
    互斥量解决线程同步问题
    Loki | 数据过期自动删除策略设计
    通过route , tracert , traceroute 查看本地路由配置及访问ip或域名时经过的路由信息
    Spring的@Async使用防坑
  • 原文地址:https://blog.csdn.net/seanyang_/article/details/126685726