美文网首页
web自动化-selenium(一)

web自动化-selenium(一)

作者: 在下YM | 来源:发表于2022-02-08 21:26 被阅读0次
    <html>
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <style>
        option,select{
            width: 100px;
        }
        option{
            height: 20px;
        }
    </style>
    
    <body>
        <form action="" method="get">
            <input type="text" id="username" name="username" placeholder="username" class='input-text'>
            <br />
            <input type="password" id="password" name="password" placeholder="password" class="input-password">
            <br />
            <input type="text" name="password2" placeholder="确认密码"><br />
        </form>
        <H8>&nbsp;</H8>
        <div id='links'>
            <ul>
                <li><a>标签</a></li>
                <li><a>Genetic Algorithms in Search, Optimization, and Machine Learning</a></li>
                <li>hello</li>
                <li>world</li>
            </ul>
        </div>
        <H8>&nbsp;</H8>
        <div>
            <button id="button" onclick="click()">我是一个按钮</button>
            <span id="click_count">鼠标单击次数: 0</span>
        </div>
        <H8>&nbsp;</H8>
        <div>
            <select name="select" id="select-single">
                <option value="1" selected>zhangsan</option>
                <option value="2">lisi</option>
                <option value="3">wangwu</option>
                <option value="4">zhaoliu</option>
                <option value="5">tangli</option>
            </select>
        </div>
        <H8>&nbsp;</H8>
        <div>
            <select name="select" id="select-multiple" multiple>
                <option value="1" selected>zhangsan</option>
                <option value="2">lisi</option>
                <option value="3">wangwu</option>
                <option value="4">zhaoliu</option>
                <option value="5">tangli</option>
            </select>
        </div>
    </body>
    <script>
    
        let click_count = 0
        let button = document.getElementById('button')
        button.onclick = function click(event) {
            click_count++;
            document.getElementById('click_count').innerHTML = `鼠标单击次数: ${click_count}`;
        }
    </script>
    
    </html>
    

    什么是Selenium

    • Selenium是一个用于Web应用程序测试的工具,可以直接调用浏览器,它支持所有主流的浏览器。

    • 最初是为网站自动化测试而开发的,但却被很多爬虫爱好者发扬光大

    • 官网:https://www.selenium.dev/

    Selenium特点

    • 开源软件:源代码开放可以根据需要来增加工具的某些功能
    • 跨平台:linux 、windows 、mac
    • 核心功能:就是可以在多个浏览器上进行自动化测试
    • 多语言:Java、Python、C#、JavaScript、Ruby等
    • 成熟稳定:目前已经被google , 百度, 腾讯等公司广泛使用
    • 功能强大:能够实现类似商业工具的大部分功能,因为开源性,可实现定制化功能

    什么是WebDriver?

    Webdriver 是一种用于控制浏览器的程序,不同的浏览器有不同的 webdriver。

    • Chrome (ChromeDriver)

    • IE(InternetExplorerDriver)

    • Opera(OperaDriver)

    • Firefox (FirefoxDriver)

    • safari(SafariDriver)

    • HtmlUnit (HtmlUnit Driver)
      webdriver 提供了对外的接口,其他程序通过这些接口控制 webdriver 与浏览器的交互。例如:我们可以写 python 程序来调用 webdriver 的接口。实际上从其他程序的角度看,webdriver 就是充当了和浏览器交互的一个桥梁。

    • 提示:
      Firefox、Chrome:对元素定位和操作有良好的支持,同时对JavaScript支持也非常好。
      IE: 只能在windows平台运行,所有浏览器中运行速度最慢
      HtmlUnit:无GUI(界面)运行,运行速度最快;

    Selenium 执行过程

    python代码--> selenium 封装的 python 接口--> WebDriver 提供接口--> 浏览器

    环境搭建

    基于Python环境搭建

    pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
    

    注意: 在安装selenium时,前提是Python3.5以上版本安装完毕且能正常运行

    谷歌浏览器驱动安装

    确认浏览器的版本


    查看方式

    下载驱动

    下载与浏览器版本一致的驱动版本

    谷歌浏览器驱动下载地址

    国内不能直接访问Chrome官网,可以在ChromeDriver仓库中下载 或者 https://npm.taobao.org/mirrors/chromedriver

    选择自己对应的平台版本

    WebDriver 元素定位简单方式

    selenium页面元素定位的方法,是在selenium中可以通过多种方式来定位标签,返回标签元素对象:

    • 通过 id 属性定位 : find_element_by_id
    • 通过 name 属性定位 : find_element_by_name
    • 通过 class 属性定位 : find_element_by_class_name
    • 通过标签名定位 : find_element_by_tag_name
    • 通过内容定位 a 标签(绝对匹配) : find_element_by_link_text
    • 通过内容定位 a 标签(模糊匹配) : find_element_by_partial_link_text
    from selenium.webdriver import Chrome
    import traceback
    from selenium.webdriver.chrome.service import *
    
    from selenium.webdriver.common.by import By
    
    service = Service("./chromedriver")
    driver = Chrome(service=service)
    # 通过指定chromedriver的路径来实例化driver对象
    
    # 控制浏览器访问url地址
    # file://{本地文件绝对路径}
    driver.get('file://./test.html')  # 打开本地 html 文件
    
    try:
        print(driver.find_element_by_id('username')) # 通过 id 属性定位
        driver.find_element_by_name('password2')  # 通过 name 属性定位
        driver.find_element_by_class_name('input-password') # 通过 class 属性定位
        driver.find_element_by_tag_name('ul') # 通过标签名定位
        driver.find_element_by_link_text('标签') # 通过内容定位 a 标签(绝对匹配)
        driver.find_element_by_partial_link_text('Optimization')  # 通过内容定位 a 标签(模糊匹配)
    except Exception:
        print(traceback.format_exc())
    finally:
        # 退出浏览器
        driver.quit()
    
    • Chrome(executable_path='./chromedriver')中executable参数指定的是下载好的chromedriver文件的路径
    • 要在代码中尽量保证driver.quit()能够成功执行,进而关闭driver退出模拟浏览器;不然将在操作系统中残留进程,对系统造成不必要的压力
    • find_element_by_方式已不推荐使用,推荐使用find_element(By_,元素)

    xpath 方式

    1. XPath 即为 XML Path 的简称,它是一种用来确定 XML/HTML 文档中某部分位置的语言。
    2. XPath文档:http://www.w3school.com.cn/xpath/index.asp
    3. HTML 可以看做是 XML 的一种实现,所以 Selenium 用户可以使用这种强大的语言在Web应用中定位元素。

    xpath路径

    • html,xml 中的元素可以嵌套其他元素,但是根元素只有一个。我们可以这种嵌套关系看成路径。路径分绝对路径和相对路径:
    • 绝对路径:从根元素到指定元素之间所有经过元素层级路径,绝对路径以 "/" 开始,例如: input 的绝对路径是: /html/body/form/input
    • 相对路径:从任何元素开始到该元素的路径,相对路径以 "//" 开始,例如: 用户名输入框标签的相对路径有: //form/input,//body/form/input

    xpath 定位

    xpath 定位是结合路径来进行定位的,分为绝对定位和相对定位。定位过程中还可以结合元素的属性值。

    定位方法是 find_element_by_xpath

    纯路径定位

    绝对定位: find_element_by_xpath("/html/body/form/input")

    相对定位: find_element_by_xpath("//div/ul/li/a")

    结合属性

    单个属性: find_element_by_xpath("//input[@type='text']")

    多个属性: driver.find_element_by_xpath("//input[@type='text' and @name='username']")

    选择上一级元素

    find_element_by_xpath("//input/..") 返回的是 form 元素

    满足条件的多个元素,选择其中一个

    driver.find_element_by_xpath("//ul/li") 有多个 li 满足条件,选择其中一个,通过下标来完成,下标从 1 开始

    driver.find_element_by_xpath("//ul/li[1]")

    可以结合特殊方法 last() 从后面开始选择 ,比如 //ul/li[last()] 选择最后一个 //ul/li[last()-1] 倒数第二个

    from selenium.webdriver import Chrome
    import traceback
    
    # 通过指定chromedriver的路径来实例化driver对象
    driver = Chrome(executable_path='./chromedriver')
    
    # 控制浏览器访问url地址
    # file://{本地文件绝对路径}
    driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件
    
    try:
        print(driver.find_element_by_xpath('/html/body/form/input'))
        print(driver.find_element_by_xpath('//div/ul/li'))
    
        print(driver.find_element_by_xpath('//form/input[@name="password"]'))
        print(driver.find_element_by_xpath('//form/input[@name="password2" and @type="text"]'))
    
        print(driver.find_element_by_xpath('//li/..'))
    
        print(driver.find_element_by_xpath('//ul/li[1]'))
        print(driver.find_element_by_xpath('//ul/li[last()]'))
        print(driver.find_element_by_xpath('//ul/li[last()-1]'))
    except Exception:
        print(traceback.format_exc())
    finally:
        # 退出浏览器
        driver.quit()
    

    CSS 方式

    CSS 选择器

    CSS 选择器参考手册

    在Selenium中也可以使用这种选择器,通过 find_element_by_css_selector:

    1. 在selenium中极力推荐CSS定位,因为它比XPath定位速度要快
    2. CSS 选择器语法非常强大,在这里我们只学习在测试中常用的几个
    选择器 例子 描述
    #id #userA id选择器,选择id="userA"的所有元素
    .class .telA class选择器,选择class="telA"的所有元素
    element input 选择所有input元素
    [attribute=value] [type="password"] 选择type="password"的所有元素
    element>element p>input 选择所有父元素为p元素的input元素
    driver.find_element_by_css_selector('#username') # 通过 id
    driver.find_element_by_css_selector('.input-text') # 通过 class
    driver.find_element_by_css_selector('form') # 通过标签名
    driver.find_element_by_css_selector('input[type="password"]') # 通过标签属性
    driver.find_element_by_css_selector('div>ul') # 通过父子元素
    

    查询多个元素

    • 通过 id 属性定位 : find_elements_by_id
    • 通过 name 属性定位 : find_elements_by_name
    • 通过 class 属性定位 : find_elements_by_class_name
    • 通过标签名定位 : find_elements_by_tag_name
    • 通过内容定位 a 标签(绝对匹配) : find_elements_by_link_text
    • 通过内容定位 a 标签(模糊匹配) : find_elements_by_partial_link_text
    • 通过 xpath : find_elements_by_xpath
    • 通过 CSS 选择器: find_elements_by_css_selector
      和选择单个元素的字面区别就是多了个 s。
    调用这类方法,会返回一个列表,没有找到元素则返回空列表,查找单个元素的方法会在找不到元素时抛出 NoSuchElementException 异常
    driver.find_elements_by_id('#no-exist-id') # 返回空数组
    
    driver.find_elements_by_tag_name('li') #  返回数组多个元素
    

    什么是元素等待?

    概念:WebDriver定位页面元素时如果未找到,会在指定时间内一直等待的过程。

    为什么要设置元素等待?

    当使用脚本定位元素或去验证程序的运行状态时,由于资源受限或网络延迟引起的响应速度太慢,导致要定位的元素还未加载到页面。

    例如:页面是通过 Ajax 发起请求,但是网络有延迟,提交按钮点击完后,页面等待服务器的返回结果来更新页面,那么在这期间,测试代码是不能够直接去查找预期的元素的。

    元素等待类型

    显式等待
    隐式等待

    显式等待

    概念:使 WebDriver 等待某个条件成立,否则在达到最大时长时抛出超时异常(TimeoutException)

    WebDriverWait 类

    from selenium.webdriver.support.wait import WebDriverWait

    参数:

    • driver: webdriver对象
    • timeout: 等待多长时间
    • poll_frequency: 每次执行失败时休眠多长时间
    调用方法

    WebDriverWait.util(method, message=''):

    参数说明:

    • method 函数,这个函数必须定义一个参数,接受 driver 对象。例如: def contain_title(driver)
    • message 如果等待失败,message 作为消息抛出
      返回值:如果找到,返回找到元素的对象
    from selenium.webdriver import Chrome
    import traceback
    from selenium.webdriver.support.wait import WebDriverWait
    driver = Chrome('./chromedriver')
    
    # 3. 打开网址
    # file://{本地网址绝对路径}
    driver.get('http://www.baidu.com')
    
    
    try:
        # time.sleep(2)
        # 1. 指定最长的等待时间,指定检测until函数的时间
        # driver对象,最长等待5s, 如果没有找到,每隔0.5s, 检测until()指定的函数,如果5s都没有找到,抛出异常
        wait_driver = WebDriverWait(driver, 5, 0.5)
    
        # WebDriverWait.until(), 需要传入一个函数名, 这个函数,参数为Chrome类型
        el = wait_driver.until(lambda temp: temp.find_element_by_tag_name('html'))
        print(el)
    
    except Exception as e:
        # print(e) # 只打印错误信息
        print(traceback.format_exc()) # 有错误路径显示
    finally:
        # 不管有没有异常,都保证driver可以关闭
        driver.quit()
    

    隐式等待

    隐式等待调用方法

    driver.implicitly_wait(10)

    隐式等待执行-说明

    如果定位某一元素定位失败,那么就会触发隐式等待有效时长,如果在指定时长内加载完毕,则继续执行,否则抛出 NoSuchElementException 异常。

    from selenium.webdriver import Chrome
    from selenium.webdriver.support.wait import WebDriverWait
    import traceback
    import time
    
    # 通过指定chromedriver的路径来实例化driver对象
    driver = Chrome(executable_path='./chromedriver')
    
    # 控制浏览器访问url地址
    driver.get('https://www.baidu.com')
    
    driver.implicitly_wait(5) # 隐式等待
    
    try:
        driver.find_element_by_id('kw')
    
    except Exception as e:
        print('type = ', type(e))
        # print(traceback.format_exc())
    finally:
        # 退出浏览器
        driver.quit()
    

    相关文章

      网友评论

          本文标题:web自动化-selenium(一)

          本文链接:https://www.haomeiwen.com/subject/lfabkrtx.html