selenium学习笔记(基于Python)

一、windows下安装及环境配置

  • Python安装,本文中安装的是2.x版本。 去下载
  • 配置环境变量:我的电脑-属性-高级系统设置-环境变量,将以下变量加入Path中
  • C:\Python27;C:\Python27\Scripts

  • 检查python是否正确安装和配置:
    Win+R输入cmd或powershell,命令行输入“python”检查,出现Python 2.7.x...等字样表示安装配置完成
  • 安装selenium:使用pip命令(最新版python 2.7或3.6都默认带有pip),命令行输入以下命令即可
  • pip install selenium

  • 下载webdriver,解压后放在path环境变量的路径下,或者与python脚本放在同一文件夹下
    Chrome驱动 ,各版本的文件夹中notes.txt标注了支持的Chrome版本,根据自己安装的Chrome版本选择即可
    Firefox驱动 ,直接下载最新版本使用
    Edge驱动
    Safari驱动

    二、知识储备

  • html+css基础
  • javascript基础,需要在脚本中执行js
  • python基础,以及 unittest 框架
  • 最基础的用法如下:

    from selenium import webdriver    #导入webdriver
    driver = webdriver.Firefox()      #创建实例并打开浏览器,此处为Firefox
    driver.get("www.google.com")      #get(url)方法打开指定URL
    assert “Google” in driver.title   #断言检测页面title是否为期望值
    driver.close()                    #关闭当前浏览器窗口
    driver.quit()                     #关闭浏览器并退出webdriver
    

    利用unittest的test suite方式:
    1、针对待测事物写test case,继承TestCase类,定义test_xxx方法
    2、在各test代码后面构造测试集,并调用runner执行测试,如:

    if __name__ == "__main__":
        suite = unittest.TestSuite()
        suite.addTest(test_xxx())
        runner = unittest.TextTestRunner()
        runner.run(suite)
    

    3、创建一个执行所有用例的文件,例如:

    import unittest
    import testCaseA, testCaseB...
    suite = unittest.TestSuite()
    suite.addTest(testCaseA.testXxx())
    suite.addTest(testCaseB.testXxx())
    if __name__ == '__main__':
        runner = unittest.TextTestRunner()
        runner.run(suite)
    

    四、元素的定位

    1.基础定位方式有如下几种:

  • find_element_by_id —— 通过id定位
  • find_element_by_name —— 通过name定位
  • find_element_by_class_name —— 通过class name定位
  • find_element_by_link_text —— 通过link text定位
  • find_element_by_partial_link_text —— 通过匹配部分link text定位
  • find_element_by_tag name —— 通过tag name定位
  • find_element_by_xpath —— 通过xpath定位
  • find_element_by_css selector —— 通过CSS选择器定位,推荐
  • 2.定位元素组

    使用find_elements_by_xxx方法,常用于批量操作对象,如勾选所有checkbox,例:

    # 选择所有的checkbox并全部勾上
    checkboxes = dr.find_elements_by_css_selector('input[type=checkbox]')
    for checkbox in checkboxes:
            checkbox.click()
    # 选择页面上所有的input,然后从中过滤出所有的checkbox并勾选之
    inputs = dr.find_elements_by_tag_name('input')
    for input in inputs:
            if input.get_attribute('type') == 'checkbox':
                    input.click()
    # 把页面上最后1个checkbox的勾给去掉
    dr.find_elements_by_css_selector('input[type=checkbox]').pop().click()
    

    3.层级定位

    层级定位:实际项目中有很多个属性基本相同的元素,需要具体定位到其中的一个,这时需要先定位父元素,然后再定位到子孙元素,如:find_element_by_id('parent').find_element_by_id('child')

    4.button group按钮组

    定位思路是先找到button group的div,然后通过层级定位,用index或者属性去定位具体的按钮,例:

    # 定位text是second的按钮
    buttons = dr.find_element_by_class_name('btn-group').find_elements_by_class_name('btn')
    for btn in buttons:
        if btn.text == 'second': print 'find second button'
    

    5.button dropdown

    button dropdown按钮把按钮和下拉菜单放在一起,处理思路是先点击这个按钮,等待下拉菜单显示后,通过层级定位获取下拉菜单中的选项,例:

    #点击下拉菜单
    dr.find_element_by_link_text('Info').click()
    #找到dropdown-menu父元素
    WebDriverWait(dr,10).until(lambda the_driver: the_driver.find_element_by_class_name('dropdown-menu').is_displayed())
    #找到better than
    menu = dr.find_element_by_class_name('dropdown-menu').find_element_by_link_text('better than')
    

    6.navs

    navs用于简单的tab导航栏,通常先定位ul再层级定位到li即可,或者直接根据link_text定位

    7.面包屑

    面包屑一般来说当前层级都没有链接,而副层级基本是链接,所以思路基本上是:先找到面包屑所在div或ul,再找到其下所有链接,这些链接就是父层级,最后不是链接的就是当前层级了

    一般分页需要知道的是:总共的页数,当前页数,是否可以上下翻页,或者直接跳转
    分页通常使用ul来实现,当前页一般是没有链接的,通过class name = active定位,其它2个信息按页面情况获取

    四、元素的操作:

    1.获取对象的属性及内容

    通过webdriver的element.attribute()方法获取dom元素属性
    获取css属性:element.value_of_css_property()

    2.获取对象的状态

    通常需要获取对象的四种状态:

  • 是否显示——使用element.is_displayed()
  • 是否存在——使用find_element_by_xxx方法,捕获抛出的一场,如果存在异常则不存在
  • 是否被选中——一般是判断表单元素是否被选中,如radio或checkbox,通过element.is_selected()方法
  • 是否enable——使用element.is_enabled()
  • 3.一些基本的操作

  • click() 点击对象
  • send_keys() 在对象上模拟按键输入或往文本框赋值(需要form selenium.webdrive.common.keys import Keys
  • clear() 清除对象内容
  • submit() 用于提交表单,特别用于没有提交按钮的情况,比如搜索框输入关键字后按回车搜索的(也可以通过模拟回车键来实现)
  • 4.执行js

    通常需要在页面上或者定位的元素上执行js,而webdriver就提供了execute_script()接口来执行js
    js = "some javascripts"
    driver.execute_script(js)

    在页面进行操作致使一些元素隐藏或出现时,或者等待ajax执行完成时,需要用到WebDriverWait的until方法等待(显式等待),需要用到的是selenium.webdriver.support.ui.WebDriverWait类,until方法会一直等下去,直到

  • 代码块中的内容为true(不为false或没有抛出异常)
  • 超时,即超过timeout设定的时间
  • 例如等待直到某元素显示

    wait = selenium.webdriver.support.ui.WebDriverWait(driver, 10)
    wait.until(lambda driver: driver.element.isdisplayed())            #lambda为Python创建匿名函数的关键字
    

    隐式等待,是指通过一定的时长等待页面所有元素加载完成,如果超出了设置的时长而元素还没有被加载则抛出NoSuchElementException异常。WebDriver提供了implicitly_wait()方法来实现隐式等待,默认设置为0.

    6.复杂的操作

    1. ActionChains模拟鼠标操作
  • perform() 执行所有ActionChains中存储的行为
  • context_click() 右击
  • double_click() 双击
  • drag_and_drop() 拖动
  • move_to_element() 鼠标悬停
  • 2.frame切换

    页面嵌套frame时,若要定位frame中的元素,需要通过switch_to_frame(id/name)方法先将定位主体切换到frame里。
    如果iframe没有id或name可以定位,则先通过其它方式先定位到frame,再将定位对象传给switch_to_frame()方法。
    如果完成了在当前frame上的操作,可以通过switch_to_default_content()方法返回上一层表单。

    3.多窗口切换

    通过switch_to_window()方法切换到任意窗口。
    current_window_handle——获得当前窗口句柄
    window_handles——返回所有窗口的句柄到当前会话
    switch_to_window(handle)——根据给的句柄切换到相应窗口

    4.警告框处理

    处理JS生成的alert、confirm以及prompt做法是通过switch_to_alert()方法定位到alert/confirm/prompt,然后使用text/accept/dismiss/send_keys执行对应操作

  • text 返回提示框中的文字信息
  • accept 点击确认按钮
  • dismiss 点击取消按钮(当存在取消按钮时可用)
  • send_keys 输入值(仅prompt可用)
  • 5.文件上传
  • 对于用过input标签实现的上传,可以将其看作一个输入框,通过send_keys()传入本地文件路径从而模拟上传功能。
  • 借助Autolt实现上传。首先通过AutoIt写好脚本并转换成exe可执行文件,然后在python中,打开上传文件对话框,再调用os.system('xxx.exe')运行exe来实现上传。
  • 6.文件下载
  • 通过编辑配置文件将文件下载到默认路径
  • 通过AutoIt脚本实现
  • 7.操作cookie
  • get_cookies() 获得所有cookie信息
  • get_cookie(name) 返回有特定name值得cookie信息
  • add_cookie(cookie_dict) 添加cookie,必须有name和value值
  • delete_cookie(name) 删除特定部分的cookie信息
  • delete_all_cookies() 删除所有的cookie信息
  • 8.窗口截图

    webdriver提供了截图函数get_screenshot_as_file()来截取当前窗口

    五、遇到的一些坑

  • 使用Chrome,登陆后总是弹出记住密码提示框——解决办法:打开Chrome时设置option选项:
  • options = webdriver.ChromeOptions()
    prefs = {"":""}
    prefs["credentials_enable_service"] = False
    prefs["profile.password_manager_enable"] = False
    options.add_experimental_option("prefs",prefs)
    driver = webdriver.Chrome(chrome_options = options)