zoukankan      html  css  js  c++  java
  • Selenium Python

    1. 什么是Selenium

      Selenium是一个免费的(开源)自动化测试组件,适用于跨不同浏览器和平台的Web应用程序。它非常类似于HP Quick Test Pro (QTP现在叫UFT),只是Selenium侧重于自动化基于Web的应用程序。使用Selenium工具进行的测试通常称为Selenium测试。

    Selenium的组成

    整个Selenium工具套件由四个组件组成:

    Selenium IDE,一个Firefox插件,您只能在创建相对简单的测试用例和测试套件时使用它。
    Selenium RC,也称为Selenium 1,它是第一个允许用户使用编程语言创建复杂测试的Selenium工具。
    WebDriver是一个新的突破,它允许您的测试脚本直接与浏览器通信,从而从操作系统级别控制它。
    Selenium Grid也是一个工具,它与Selenium RC一起用于跨不同的浏览器和操作系统执行并行测试。
    Selenium RC与WebDriver合并形成Selenium 2,现已经更新到了Selenium 3 和Selenium 4。

    Selenium的优点

    Selenium在成本和灵活性方面比QTP更有优势。它还允许您并行地运行测试,而不像在QTP中,您只允许顺序地运行测试。

      • 成本(因为Selenium是完全免费的)
      • 灵活性(因为Selenium可以支持多种编程语言、浏览器和平台)
      • 并行测试(这是QTP能够做到的,但只有使用质量中心)

    Quick Test Professional(QTP)是一种专有的自动化测试工具,在2006年被惠普收购之前,它曾属于Mercury Interactive公司。

    2. Selenium3 浏览器驱动

    下载浏览器驱动

    下载Driver要注意和你当前已有的浏览器的版本是否一致

    Chrome浏览器驱动:chromedriver 

    IE浏览器驱动:IEDriverServer

    Edge浏览器驱动:MicrosoftWebDriver

    设置浏览器驱动

    我的电脑-->属性-->系统设置-->高级-->环境变量-->系统变量-->Path,将存放浏览器驱动的目录添加到Path的值中。

    或者 浏览器驱动放到与python.exe同级目录中

    3. selenium元素定位

      Selenium提供了8种定位方式。

    1. id
    2. name
    3. class name
    4. tag name
    5. link text
    6. partial link text
    7. xpath
    8. css selector

      这8种定位方式在Python selenium中所对应的方法为:

    1. find_element_by_id()
    2. find_element_by_name()
    3. find_element_by_class_name()
    4. find_element_by_tag_name()
    5. find_element_by_link_text()
    6. find_element_by_partial_link_text()
    7. find_element_by_xpath()
    8. find_element_by_css_selector()

    #通过id定位:
    dr.find_element_by_id("kw")
    #通过name定位:
    dr.find_element_by_name("wd")
    #通过class name定位:
    dr.find_element_by_class_name("s_ipt")
    #通过tag name定位:
    dr.find_element_by_tag_name("input")
    #通过xpath定位,xpath定位有N种写法,这里列几个常用写法:
    dr.find_element_by_xpath("//*[@id='kw']")
    dr.find_element_by_xpath("//*[@name='wd']")
    dr.find_element_by_xpath("//input[@class='s_ipt']")
    dr.find_element_by_xpath("/html/body/form/span/input")
    dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
    dr.find_element_by_xpath("//form[@id='form']/span/input")
    dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
    #通过css定位,css定位有N种写法,这里列几个常用写法:
    dr.find_element_by_css_selector("#kw")
    dr.find_element_by_css_selector("[name=wd]")
    dr.find_element_by_css_selector(".s_ipt")
    dr.find_element_by_css_selector("html > body > form > span > input")
    dr.find_element_by_css_selector("span.soutu-btn> input#kw")
    dr.find_element_by_css_selector("form#form > span > input")
    # 通过link text定位:
    dr.find_element_by_link_text("新闻")
    dr.find_element_by_link_text("hao123")
    # 通过link text定位:
    dr.find_element_by_partial_link_text("")
    dr.find_element_by_partial_link_text("hao")
    dr.find_element_by_partial_link_text("123")

    3.1 通过Xpath定位

    Xpath语法

    https://www.w3school.com.cn/xpath/xpath_syntax.asp

    一:从根目录/开始

    有点像Linux的文件查看,/代表根目录,一级一级的查找,直接子节点,相当于css_selector中的>号

    /html/body/div/p 

    二. 根据元素属性选择:

    查找具体的元素,必须在前面输入标准开头//,表示从当前节点寻找所有的后代元素

    //div/*     div下面的所有的元素

    //div//p     先在整个文档里查找div,再在div里查找p节点(只要在内部,不限定是否紧跟) ;等价于 css_selector里的('div p')

    //div/p      p是div的直接子节点; 等价于 css_selector里的('div > p')

    //*[@style]   查找所有包含style的所有元素,所有的属性要加@;  等价于 css_selector里的('*[style]')

    //p[@spec='len']  必须要加引号;等价于 css_selector里的("p[spec='len']")

    //p[@id='kw']    xpath中对于id,class与其他元素一视同仁,没有其他的方法

    //a[contains(@href,'permalink')]  href属性中包含permalink的a

    //input[@type='text' and @name='wd'] 多个属性组合(逻辑运算)

    //input[starts-with(@class,'s_ip')]   模糊匹配以xx开头:starts-with

            //*[text()=‘文本内容’]   对于这种文本属性

    三. 选择第几个节点

    //div/p[2]   选择div下的第二个p节点 ;等价于css_selector里的div>p:nth-of-type(2)  符合p类型的第二个节点

    //div/*[2]    选择div下第二个元素

    //div/p[position()=2]   position()=2   指定第二个位置;  等价于上面的 //div/p[2] 

              position()>=2      位置大于等于2

              position()<2        位置小于2

              position()!=2    位置不等于2

    //div/p[last()]    选择div下的倒数第一个p节点; last()倒数第一个

    //div/p[last()-1]    选择div下的倒数第二个p节点;

    //div/p[position()=last()]     倒数第一个

    //div/p[position()=last()-1]     倒数第二个

    //div/p[position()>=last()-2]     倒数第一个,第二个,第三个

    四. 组合选择

    //p | //button   选择所有的p和button,等价于css_selector里的 p, button

    //input[@id='kw' and @class='su']     选择id=kw 并且 class="su"的input元素

    五. 兄弟节点的选择

    相邻后面的兄弟节点的选择:following-sibling::    两个冒号

    //div/following-sibling::p    选择div里相邻的p节点

    相邻前面的兄弟节点的选择:preceding-sibling::         此方法在css_selector中没有

    //div/preceding-sibling::p[2]   选择div里前面相邻的第二个节点,不加[2]选择的是前面的所有的p节点

    六. 选择父节点    

    //p[@spec='len']/..    选择p节点的上层节点       此方法在css_selector中没有

    //p[@spec='len']/../..   上层节点的上层节点

     七. 在webelement对象里面使用查找Xpath 查找时,必须使用.指明当前节点

    food = driver.find_element_by_id('food')

    eles = food.find_elements_by_xpath(".//p")    .指明当前节点

    eles = food.find_elements_by_xpath("..")   查找当前节点的父节点 

    3.2 通过CSS Selector 定位

    一:通过ID定位

    find_element_by_css_selector("#Email")
    find_element_by_css_selector("input#Email")

    二:通过Class定位

    find_element_by_css_selector(".remember")
    find_element_by_css_selector("label.remember")

    三:  通过属性定位

    find_element_by_css_selector("input")

    find_element_by_css_selector("[name='wd']")

    find_element_by_css_selector("input[type=’submit’]")

    四:  通过位置定位

    find_element_by_css_selector("span input")

    find_element_by_css_selector("span > input")

    find_element_by_css_selector("span + input.s_ipt")

    find_element_by_css_selector("ul > li:nth-chlid(2)")

    五:  常用CSS Selector

    パターン意味

    *

    任意的元素    

    E

    Type E 的元素

    E[foo]

    有"foo" 属性的 E 元素

    E[foo="bar"]

    "foo" 属性値等于 "bar" 的 E 元素

    E[foo^="bar"]

    "foo" 属性値 "bar" 开始的 E 元素

    E[foo$="bar"]

    "foo" 属性値 "bar" 结尾的 E 元素

    E[foo*="bar"]

    "foo" 属性値含有 "bar" 的 E 元素

    E:root

    E 元素 (document的根)

    E:nth-child(n)

    E 元素 (親から n 番目の子)

    E:nth-last-child(n)

    E 元素 (最後の元素から数えて、親の n 番目の子元素)

    E:nth-of-type(n)

    E 元素 (同タイプの n 番目の兄弟)

    E:nth-last-of-type(n)

    E 元素 (最後の元素から数えて、そのタイプの n 番目の兄弟元素)

    E:first-child

    E 元素 (親の最初の子)

    E:last-child

    E 元素 (親の最後の子)

    E:first-of-type

    E 元素 (同タイプの最初の兄弟)

    E:last-of-type

    E 元素 (同タイプの最後の兄弟)

    E F

    E 元素の子孫 F 元素

    E > F

    E 元素の子 F 元素

    E + F

    E 元素の直後の F 元素

    E ~ F

    E 元素の後のF 元素

     

    4. 控制浏览器操作

     设置浏览器的大小 

      driver.set_window_size(480, 800)

     控制浏览器后退、前进

        driver.back()

        driver.forward()

     刷新页面

        driver.refresh()

    from selenium import webdriver
    
    driver = webdriver.Firefox()
    
    #访问百度首页
    first_url= 'http://www.baidu.com'
    print("now access %s" %(first_url))
    driver.get(first_url)
    
    # 参数数字为像素点
    print("设置浏览器宽480、高800显示")
    driver.set_window_size(480, 800)
    
    #访问新闻页面
    second_url='http://news.baidu.com'
    print("now access %s" %(second_url))
    driver.get(second_url)
    
    #返回(后退)到百度首页
    print("back to  %s "%(first_url))
    driver.back()
    
    #前进到新闻页
    print("forward to  %s"%(second_url))
    driver.forward()
    
    driver.refresh() #刷新当前页面
    
    driver.quit()
    View Code

    5. WebDriver常用方法

     点击和输入

      clear(): 清除文本。

      send_keys (value): 模拟按键输入。

      click(): 单击元素。

     提交

        submit()

     其他常用方法

        size: 返回元素的尺寸。

        text: 获取元素的文本。

        get_attribute(name): 获得属性值。

        is_displayed(): 设置该元素是否用户可见。

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    
    # 获得输入框的尺寸
    size = driver.find_element_by_id('kw').size
    print(size)
    
    # 返回百度页面底部备案信息
    text = driver.find_element_by_id("cp").text
    print(text)
    
    # 返回元素的属性值, 可以是 id、 name、 type 或其他任意属性
    attribute = driver.find_element_by_id("kw").get_attribute('type')
    print(attribute)
    
    # 返回元素的结果是否可见, 返回结果为 True 或 False
    result = driver.find_element_by_id("kw").is_displayed()
    print(result)
    
    driver.find_element_by_id("kw").clear()
    driver.find_element_by_id("kw").send_keys("selenium")
    driver.find_element_by_id("su").click()
    
    search_text.submit()
    
    driver.quit()
    View Code

    6. 鼠标事件

       perform(): 执行所有 ActionChains 中存储的行为;

    context_click(): 右击;

    double_click(): 双击;

    drag_and_drop(): 拖动;

    move_to_element(): 鼠标悬停。 

    from selenium import webdriver
    # 引入 ActionChains 类
    from selenium.webdriver.common.action_chains import ActionChains
    
    driver = webdriver.Chrome()
    driver.get("https://www.baidu.cn")
    
    # 定位到要悬停的元素
    above = driver.find_element_by_link_text("设置")
    # 对定位到的元素执行鼠标悬停操作
    ActionChains(driver).move_to_element(above).perform()

    7. 键盘事件

    在使用键盘按键方法前需要先导入 keys 类。

    from selenium.webdriver.common.keys import Keys

    from selenium import webdriver
    # 引入 Keys 模块
    from selenium.webdriver.common.keys import Keys
    
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    
    # 输入框输入内容
    driver.find_element_by_id("kw").send_keys("seleniumm")
    
    # 删除多输入的一个 m
    driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
    
    # 输入空格键+“教程”
    driver.find_element_by_id("kw").send_keys(Keys.SPACE)
    driver.find_element_by_id("kw").send_keys("教程")
    
    # ctrl+a 全选输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')
    
    # ctrl+x 剪切输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')
    
    # ctrl+v 粘贴内容到输入框
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')
    
    # 通过回车键来代替单击操作
    driver.find_element_by_id("su").send_keys(Keys.ENTER)
    driver.quit()

      以下为常用的键盘操作:

    send_keys(Keys.BACK_SPACE) 删除键(BackSpace)

    send_keys(Keys.SPACE) 空格键(Space)

    send_keys(Keys.TAB) 制表键(Tab)

    send_keys(Keys.ESCAPE) 回退键(Esc)

    send_keys(Keys.ENTER) 回车键(Enter)

    send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)

    send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)

    send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)

    send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)

    send_keys(Keys.F1) 键盘 F1

    8. 获取信息

    不管是在做功能测试还是自动化测试,最后一步需要拿实际结果与预期进行比较。这个比较的称之为断言。

    我们通常可以通过获取title 、URL和text等信息进行断言。

    title:用于获得当前页面的标题。

    current_url:用户获得当前页面的URL。

    text:获取搜索条目的文本信息。

    # 打印当前页面title
    title = driver.title
    print(title)
    
    # 打印当前页面URL
    now_url = driver.current_url
    print(now_url)
    
    # 获取结果数目
    user = driver.find_element_by_class_name('nums').text
    print(user)

    9. 设置元素等待

    WebDriver提供了两种类型的等待:显式等待和隐式等待。

    显式等待

    显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。

    WebDriverWait类是由WebDirver 提供的等待方法。.

    在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常

    WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

     ◆ driver :浏览器驱动。

     ◆ timeout :最长超时时间,默认以秒为单位。

     ◆ poll_frequency :检测的间隔(步长)时间,默认为0.5S。

     ◆ ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常。

        WebDriverWait()一般由until()或until_not()方法配合使用,下面是until()和until_not()方法的说明。

     ◆ until(method, message=‘’)
    调用该方法提供的驱动程序作为一个参数,直到返回值为True。

    until_not(method, message=‘’)
    调用该方法提供的驱动程序作为一个参数,直到返回值为False。

    在本例中,通过as关键字将expected_conditions 重命名为EC,并调用presence_of_element_located()方法判断元素是否存在。

    隐式等待

     implicitly_wait() 默认参数的单位为秒

    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    from time import ctime
    
    driver = webdriver.Firefox()
    
    # 设置隐式等待为10秒
    driver.implicitly_wait(10)
    driver.get("http://www.baidu.com")
    
    try:
        print(ctime())
        driver.find_element_by_id("kw22").send_keys('selenium')
    except NoSuchElementException as e:
        print(e)
    finally:
        print(ctime())
        driver.quit()

    本例中设置等待时长为10秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速度。

    它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;

    如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。

    假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。

    10. 定位一组元素

    • find_elements_by_id()
    • find_elements_by_name()
    • find_elements_by_class_name()
    • find_elements_by_tag_name()
    • find_elements_by_link_text()
    • find_elements_by_partial_link_text()
    • find_elements_by_xpath()
    • find_elements_by_css_selector()

    11. 多表单切换

    driver.switch_to.frame('frameId')

    driver.switch_to.parent_frame()

    driver.switch_to.default_content()

    driver = webdriver.Chrome()
    driver.get("http://www.126.com")
    
    driver.switch_to.frame('x-URS-iframe')
    driver.find_element_by_name("email").clear()
    driver.find_element_by_name("email").send_keys("username")

    当ID是随机内容,不可用的时候,直接定位frame(0) 即第一个frame

    driver.switch_to.frame(0) 

    12. 多窗口切换

     current_window_handle:获得当前窗口句柄。 

    window_handles:返回所有窗口的句柄到当前会话。 

    switch_to.window(handle):用于切换到相应的窗口,用于不同表单之间的切换。 

    from selenium import webdriver
    import time
    
    driver = webdriver.Firefox()
    driver.implicitly_wait(10)
    driver.get("http://www.baidu.com")
    
    # 获得百度搜索窗口句柄
    sreach_windows = driver.current_window_handle
    
    driver.find_element_by_link_text('登录').click()
    driver.find_element_by_link_text("立即注册").click()
    
    # 获得当前所有打开的窗口的句柄
    all_handles = driver.window_handles
    
    # 进入注册窗口
    for handle in all_handles:
        if handle != sreach_windows:
            driver.switch_to.window(handle)
            print('now register window!')
            driver.find_element_by_name("account").send_keys('username')
            driver.find_element_by_name('password').send_keys('password')
            time.sleep(2)
            # ……
    
    driver.quit()

    13. 警告框处理

    switch_to_alert() : 接受这个弹窗。  

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

    accept():接受现有警告框。 

    dismiss():解散现有警告框。 

    send_keys(keysToSend):发送文本至警告框。keysToSend:将文本发送至警告框。 

    # 接受警告框
    driver.switch_to.alert.accept()

    14. 下拉框选择

    from selenium.webdriver.support.select import Select

    Select类用于定位select标签。

    select_by_value() 方法用于定位下接选项中的value值。

    # 搜索结果显示条数
    sel = driver.find_element_by_xpath("//select[@id='nr']")
    Select(sel).select_by_value('50')  # 显示50条

    15. 文件上传

    对于通过input标签实现的上传功能,可以将其看作是一个输入框,即通过send_keys()指定本地文件路径的方式实现文件上传。

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

    16. cookie操作

    WebDriver操作cookie的方法:

    get_cookies(): 获得所有cookie信息。

    get_cookie(name): 返回字典的key为“name”的cookie信息。 

    add_cookie(cookie_dict) : 添加cookie。“cookie_dict”指字典对象,必须有name 和value 值。 

    delete_cookie(name,optionsString):删除cookie信息。“name”是要删除的cookie的名称,“optionsString”是该cookie的选项,目前支持的选项包括“路径”,“域”。 

    delete_all_cookies(): 删除所有cookie信息。 

    from selenium import webdriver
    
    driver = webdriver.Firefox()
    driver.get("http://www.youdao.com")
    
    # 向cookie的name 和value中添加会话信息
    driver.add_cookie({'name': 'key-aaaaaaa', 'value': 'value-bbbbbb'})
    
    # 遍历cookies中的name 和value信息并打印,当然还有上面添加的信息
    for cookie in driver.get_cookies():
        print("%s -> %s" % (cookie['name'], cookie['value']))
    
    driver.quit()

    17. 调用JavaScript代码

        driver.execute_script()

    # 通过javascript设置浏览器窗口的滚动条位置
    js="window.scrollTo(100,450);"
    driver.execute_script(js)
    sleep(3)
    这样可以实现滚动到指定元素
    element.location_once_scrolled_into_view

    18. 调用JavaScript代码窗口截图

    # 截取当前窗口,并指定截图图片的保存位置
    driver.get_screenshot_as_file("D:\baidu_img.jpg")

    19. 关闭浏览器

    close() 关闭单个窗口 

    quit() 关闭所有窗口 

    ————————————————————————————————————————————————————————————————
    参考链接:

    1. https://blog.csdn.net/u012941152/java/article/details/83011110  作者 雪国的花儿

    2. https://blog.csdn.net/zbj18314469395/article/details/99652088   作者 

    3. http://www.testclass.net/selenium_python  主要参考 作者 虫师

     

  • 相关阅读:
    java file文件类操作使用方法大全
    java 中可以在方法中 新建 方法吗
    java InputStream读取数据问题
    file 创建方法
    java中File类的使用方法
    jquery怎么获取radio的值
    //初始化无限滚动分页组件
    表单提交 封装成json格式
    几个常用EL表达式的用法
    简单的顺序队列
  • 原文地址:https://www.cnblogs.com/changxinblog/p/13168823.html
Copyright © 2011-2022 走看看