• 2.自动化测试之python+selenium基础


    元素的定位     浏览器控制    鼠标事件          键盘事件         获取验证
            sleep休眠     多表单切换      多窗口切换       
         上传文件      
                
     
    一、元素的定位

    1.webdriver提供的8种页面元素定位方法:

        id/name/class name/tag name/link text/partial link text/xpath/css selector
        其中python对应的8种方法:
        find_element_by_id()                       如: find_element_by_id("kw")  
        find_element_by_name()                     如: find_element_by_name("wd")
        find_element_by_class_name()               如: find_element_by_class_name("s_ipt") 
        find_element_by_tag_name()                 如: find_element_by_tag_name("input") 
        find_element_by_link_text()                如:find_element_by_link_text(u"新闻")    
        find_element_by_partial_link_text()        如:find_element_by_partial_link_text(u"一个很长的") 
        find_element_by_xpath()                    如: find_element_by_xpath(" .//*[@id='kw']")  
        find_element_by_css_selector()             如: find_element_by_css_selector("#kw")
        注意:
        a.python对中文支持不好,在对于有中文的地方加小写u,作用是把中文字符串转换成unicode编码,如上面link_text(u"新闻")  
        b.xpath中如果不想指定标签名,也可用(*)代替,
    2.xpath定位
        2.1 绝对路径定位:find_element_by_xpath("/html/body/div/div[2]/div/form/span/input") 
        2.2 利用元素属性定位:find_element_by_xpath("//*/input[@id='kw']")                      //表示当前目录  
        2.3 层级与属性结合:find_element_by_xpath("//span[@class='bg s_pt']/input")         /input表示父元素下的子元素
                            可以用这种方法,一层层网上,直到最外层<html>标签
        2.4 使用逻辑运算符:find_element_by_xpath("//input[@id='kw' and @class='su']/span/input")
    3.css定位        速度快于xpath
        css常见语法:
                    
        例如:
            通过.class定位的:  find_element_by_css_selector(".intr")
            通过#id定位的:     find_element_by_css_selector("#firstname")
            通过标签名定位的:  find_element_by_css_selector("input")
            通过父子关系定位的:find_element_by_css_selector("div>input")
            通过属性定位:      find_element_by_css_selector("input[type='submit']")
            组合定位:          find_element_by_css_selector(span.bg s_ipt>input.s_ipt)  
                                                //父标签span对应class属性为bg s_ipt的节点下的子标签input且这个子标签class属性为s_ipt   
     
    二、浏览器控制
        1.控制浏览器大小:set_window_size()    例如:driver.set_window_size(400,500)
                          maximize_window()    例如:driver.maximize_window()  #无参数
        2.浏览器后退、前进:back()-后退、farward()-前进
     
    三、鼠标事件
        ActionChains类提供的常用方法:
            1.1 perform():执行ActionChains中存储的所有行为,对整个事件进行提交
            1.2 context_click():    右击
            如:
               from selenium.webdriver.common.action_chains import ActionChains
                    ...
               ActionChains(dr).context_click(docfile).perform()
            1.3 double_click():     双击
            如:
               from selenium.webdriver.common.action_chains import ActionChains
                    ...
               doubleClick=dr.find_element_by_id("xxx")
               ActionChains(dr). double_Click(doubleClick).perform()        
            1.4 drag_and_drop(source,target):    拖动
            如:
                from selenium.webdriver.common.action_chains import ActionChains
                    ...
                dsource=dr.find_element_by_id("xxx")        #拖动的源元素
                dtarget=dr.find_element_by_id("xxx")        #释放的目标目标元素
               ActionChains(dr).drag_and_drop(dsource,dtarget).perform()
            1.5 move_to_element():  鼠标悬停
            如:
               from selenium.webdriver.common.action_chains import ActionChains
                    ...
               above=dr.find_element_by_id("xxx")
               ActionChains(dr).move_to_element(above).perform()
    四、键盘事件    
        1.首先要导入键盘事件的包
    1. from selenium.webdriver.common.keys importKeys
    2. ...
    3. dr.get("http://www.baidu.com")
    4. #输入内容
    5. dr.find_element_by_id("kw").send_keys("seleniumm")
    6. #删除输入内容的最后一个字母,
    7. dr.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
    8. #输入:空格+教程
    9. dr.find_element_by_id("kw").send_keys(Keys.SPACE)
    10. dr.find_element_by_id("kw").send_keys(u"教程")
    11. #ctrl+a全选输入框内容
    12. dr.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
    13. #ctrl+x剪贴输入框内容
    14. dr.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
    15. #ctrl+v剪贴输入框内容
    16. dr.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
    17. #回车键操作
    18. dr.find_element_by_id("su").send_keys(Keys.ENTER)
    19. dr.close()
        常用的键盘操作整理:
        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+x
        send_keys(Keys.F1)          #F1,类似的有F1-F12
    五、获取验证
        1.通常用到的验证信息有:title、URL、text
    dr.title
    dr.current_url
    dr.find_element_by_id("xx").text
     六、设置等待    
        1.显示等待:等待某个条件成立时,继续执行,否则达到最大等待时间后抛出异常:TimeoutException,显示等待是针对当前要定位元素使用
    WebDriverWait(driver, timeout,poll_frequency,ignored_exceptions=None).until(method,message)    
    示例:
    WebDriverWait(dr,5,0.5,None).until(
        expected_conditions.presence_of_element_located((By.ID,"kw1")),message='test') 
    解释:
    A.WebDriverWait():在设置时间内,默认间隔一段时间检测一次当前页面元素是否存在,若超过当前指定时间检测不到则抛出异常;
    B.driver:webdriver的浏览器驱动,ie、firefox、chromea
    C.timeout:最长超时时间,以秒为单位
    D.poll_frequency:休眠间隔时间-步长,默认0.5秒
    E.ignored_exceptions:超时后异常信息,默认抛出NoSuchElementException异常
    F.until(method,message): 调用该方法提供的驱动作为一个参数,直到返回值为True
    G.until_not(method,message):调用该方法提供的驱动作为一个参数,直到返回值为False
    H.expected_conditions类提供的预期条件实现有:
        title_is:判断标题是否是xx
        title_contains:判断标题是否包含xx
        presence_of_element_located:元素是否存在
        visibility_of_element_located:元素是否存在
        visibility_of:是否可见
        presence_of_all_elements_located:判断一组元素是否存在
        text_to_be_present_in_element:判断元素是否有xx文本信息  
        text_to_be_present_in_element_value:判断元素值是否有xx文本信息  
        frame_to_be_available_and_switch_to_it:表单是否可见,并切换到该表单
        invisibility_of_element_located:判断元素是否隐藏
        element_to_be_clickable:判断元素是否点击,它处于可见和启动状态
        staleness_of:等到一个元素不再依附于DOM
        element_to_be_selected:被选中的元素
        element_located_to_be_selected:一个期望的元素位于被选中
        element_selection_state_to_be:一个期望检查如果给定元素被选中
        element_located_selection_state_to_be:期望找到一个元素并检查是否是选择状态
        alert_is_present:预期一个警告信息  
        2.隐式等待:通过一定的时长等待页面所有元素加载完成,哪个元素超出设置时长没被加载就抛出异常NoSuchElementException,隐式等待是针对所有元素的
     
            implicitly_wait(5)    #默认单位为秒
        示例:
            dr.implicitly_wait(5)
    七、sleep休眠    python中强制的程序等待
        from time import sleep
        sleep(4)    #默认单位秒,设置小于1秒的时间可以用小数点如sleep(0.6)
    八、定位一组元素,类似与1中定位单个元素方法
        find_elements_by_id()                     如: find_elements_by_id("kw")  
        find_elements_by_name()                   如: find_elements_by_name("wd")
        find_elements_by_class_name()             如: find_elements_by_class_name("s_ipt") 
        find_elements_by_tag_name()               如: find_elements_by_tag_name("input") 
        find_elements_by_link_text()              如:find_elements_by_link_text(u"新闻")    
        find_elements_by_partial_link_text()      如:find_elements_by_partial_link_text(u"一个很长的") 
        find_elements_by_xpath()                  如: find_elements_by_xpath(" .//*[@id='kw']")  
        find_elements_by_css_selector()           如: find_elements_by_css_selector("#kw")
        使用场景:
        a.批量操作对象,如选中页面上所有复选框
        b.先获取一组对象,再在这组对象里定位需要的的一些对象,如定位所有复选框,然后选择最后一个
       例如:代码如下
    checkbox.htm页面:
    1. <styletype="text/css">
    2. body{font-size:12px; font-family:Tahoma;}
    3. .checkbox{vertical-align:middle; margin-top:0;}
    4. </style>
    5. <body>
    6. <inputclass="checkbox"type="checkbox"/>元旦
    7. <inputtype="checkbox"name="test"/>圣诞节
    8. <inputtype="checkbox"name="test"/>股市
    9. <inputtype="checkbox"name="test"/>阿凡达
    10. <inputtype="checkbox"name="test"/>十月围城
    11. <inputtype="checkbox"name="test"/>水价上调
    12. <inputtype="button"value="检测"id="btn"/>
    13. </body>
    python代码: 
    1.    from selenium import webdriver
    2.  
    3.     dr=webdriver.Firefox()
    4.     dr.get("D:\workspace\pySelenium\resources\checkbox.htm")
    5. #使用tagname方式选择页面上所有tagname为input的元素
    6. select_tagname=dr.find_elements_by_tag_name("input")
    7. #使用xpath方式选择页面上所有tagname为input的元素
    8. select_xpath=dr.find_elements_by_xpath("//input[@type='checkbox']")
    9. #使用css_select方式选择页面上所有tagname为input的元素
    10. select_css=dr.find_elements_by_css_selector('input[type=checkbox]')
    11. for i in select_tagname:
    12. #循环对每个input元素进行点击选中操作
    13. if i.get_attribute("type")=='checkbox':
    14. i.click()
    15. for j in select_xpath:
    16. #循环对每个input元素进行点击取消操作
    17. j.click()
    18. for k in select_css:
    19. #循环对每个input元素进行点击选中操作
    20. k.click()
    21. #打印出checkbox的个数
    22. print'----页面上checkbox的个数为:',len(select_css)
    23. #使用pop()获取1组元素的第几个元素
    24. select_css.pop(0).click()#第一个
    25. select_css.pop(1).click()#第二个
    26. select_css.pop().click()#最后一个
    27. select_css.pop(-1).click()#最后一个
    28. select_css.pop(-2).click()#倒数第二个
    29. dr.close()
        备注:pop():选择一组元素中的某一个,要注意的是:pop()和pop(-1)都表示最后一个元素
    九、多表单切换(对于有frame嵌套表单的操作)
    frame页面:
    1. <html>
    2. <body>
    3. <frameset>
    4. <h3>frame</h3>
    5. <iframeid='frameid'name='frameName'width="800"height="500"src="http://www.baidu.com"/>
    6. </frameset>
    7. </body>
    8. </html>
    python代码:
    1. dr.get("D:\workspace\pySelenium\resources\frame.htm")
    2. dr.switch_to_frame("frameid")#通过frame的id进入iframe
    3. #dr.switch_to_frame("frameName") #通过frame的name进入iframe
    4. #下面可以对frame进行操作了
    5. dr.find_element_by_id("kw").send_keys("selenium")
    6. dr.find_element_by_id("su").click()
    7. dr.switch_to_default_content()#退出当前frame返回上一层
    备注:1.switch_to_frame()默认直接取表单的id或者name属性来切换
          2.完成当前frame表单操作后,可以通过switch_to_default_content()方法返回上一层表单,即离的最近的switch_to_frame()方法    
          3.对于frame中没有id和name属性的通过下面方式进入frame(定位到frame以页面对象传入)
    python代码:
    1. dr.get("D:\workspace\pySelenium\resources\frame.htm")
    2.  #定位到frame页面元素
    3.     framepath=dr.find_element_by_class_name("frameClassname")
    4.     dr.switch_to_frame(framepath)#通过frame页面对象进入iframe
    5. #下面可以对frame进行操作了
    6. dr.find_element_by_id("kw").send_keys("selenium")
    7. dr.find_element_by_id("su").click()
    8. dr.switch_to_default_content()#退出当前frame返回上一层
    十、多窗口切换
        selenium-webdriver中使用switch_to_window()方法来切换任意窗口,常用方法有
              driver.current_window_handle    #获取当前窗口句柄
          driver.window_handles            #返回所有窗口句柄到当前会话
          driver.switch_to_window()       #进入窗口,用于切换不同窗口
     
    python代码:    
    1. dr.get("http://www.baidu.com")
    2. current_handle=dr.current_window_handle #获取百度首页窗口句柄
    3. index_login=dr.find_element_by_xpath("//div[@id='u1']/a[@class='lb']")#获取登录按钮对象
    4. index_login.click()#点击登录
    5. dr.implicitly_wait(5)
    6. dr.find_element_by_class_name("pass-reglink").click()#点击立即注册按钮
    7. all_handles=dr.window_handles #获取所有打开窗口句柄
    8. for handle in all_handles:
    9. if handle==current_handle:
    10. dr.switch_to_window(handle)
    11. '''
    12. ...对首页窗口进行操作
    13. '''
    14. print'----首页页面title:',dr.title
    15. for handle in all_handles:
    16. if handle!=current_handle:
    17. dr.switch_to_window(handle)
    18. '''
    19. ...对注册窗口进行操作
    20. '''
    21. print'----注册页面title:',dr.title
    十一、警告框处理
        webdriver中处理js生成的alert、confirm、prompt处理方法是:使用switch_to_alert()定位到alert/confirm/prompt,然后使用text、accept、dismiss、send_keys来根据需要操作。
        text:返回alert、confirm、prompt中的文字信息
        accept:点击确认按钮
        dismiss:点击取消按钮
        send_keys:在alert、confirm有对话框时输入值
    python代码:
    1. dr.get("http://www.baidu.com")
    2. set_link=dr.find_element_by_xpath("//div[@id='u1']/a[@class='pf']")#找到设置链接元素
    3. ActionChains(dr).move_to_element(set_link).perform()#鼠标移动到设置上
    4. dr.find_element_by_xpath("//a[@class='setpref']").click()#点击搜索设置链接
    5. time.sleep(3)    #加等待时间 等按钮可用,否则会报错
    6. save_set=dr.find_element_by_css_selector("#gxszButton > a.prefpanelgo")#获取保存设置按钮
    7. save_set.click()#点击保存设置按钮
    8.  
    9. alert=dr.switch_to_alert()                    #进入alert
    10. print'----弹出alert中内容为:',alert.text #打印对话框里的文字内容
    11. alert.accept()#对话框里点击alert中确定按钮
    12. #alert.dismiss() #对话框里点击取消按钮
    13. #alert.send_keys("对话框中输入的内容") #在对话框里输入内容
    十二、上传文件
        分2种:普通上传、插件上传
        普通上传:将本地文件的路径作为一个值放到input标签中,通过form表单提交时,将值传给服务器中去
        插件上传:指基于flash、javascript或ajax技术实现的上传功能或插件。
        1.针对普通上传用send_keys实现
    python代码:
    1. dr.get("D:\workspace\pySelenium\resources\upload.htm")
    2. loadFile=dr.find_element_by_name("filebutton")# 获取上传文件input元素节点
    3. loadFile.send_keys("D:\workspace\pySelenium\resources\frame.htm")#输入上传文件地址来实现上传
        2.插件上传:使用AutoIt实现,--需要安装AutoIt程序
            AutoIt安装,使用暂时略,需要时再追加,流程为:用AutoIt编写上传文件脚本生成exe文件,在python脚本中进行调用
    python代码:
    1. loadFile=dr.find_element_by_name("filebutton")# 获取上传按钮
    2. loadFile.click()    #点击上传按钮,弹出上传对话框
    3. os.system("D:\autoItFile.exe")    #调用autoIt生成的exe文件,实现导入
    十三、下载文件:使用AutoIt实现,--需要安装AutoIt程序,方法同上传
    python代码:
    1. ffp=webdriver.FirefoxProfile()
    2. ffp.set_preference("browser.download.folderList",2)#0:代表下载到浏览器默认路径下;2:下载到指定目录
    3. ffp.set_preference("browser.download.manager.showWhenStarting",False)#是否显示开始:True:显示;False:不显示
    4. ffp.set_preference("browser.download.dir", os.getcwd())#指定下载文件目录,os.getcwd()无参数,返回当前目录
    5. # ffp.set_preference("browser.helperApps.neverAsk.saveToDisk","application/octet-stream")#下载文件类型,
    6. #指定下载页面的content-type值,application/octet-stream为文件类型,http-content-type常用对照表搜索百度
    7. dr=webdriver.Firefox(firefox_profile=ffp)
    8. dr.get("https://pypi.python.org/pypi/selenium#downloads")
    9. dr.find_element_by_xpath("//div[@id='content']/div[3]/table/tbody/tr[3]/td[1]/span/a[1]").click()
    10. #接下来使用autoIt实现
    十四、cookies操作
        webdriver操作cookies的方法:
        get_cookies():获得所有cookies的值
        get_cookie(name):获得有特定name值的cookie信息
        add_cookie(cookie_dict):添加cookie,必须有name和value
        delete_cookie(name):删除特定名称的cookie信息,通过name找到特定的cookie并删除
        delete_all_cookies():删除浏览器中所有cookie的信息
        注意:1.cookie是以字典形式进行存储的;
        2.使用场景:如登录功能会把用户名写入浏览器cookie指定key为username,那么就可以通过get_cookies()找到username,打印value,找不到说明保存浏览器的cookie是有bug的。
    python代码:
    1. num=1
    2. dr.get("http://www.baidu.com")
    3. cookies=dr.get_cookies()#获取cookie的所有信息
    4. for ck in cookies:
    5. print'----所有cookie',num,':',ck #打印cookie的所有信息
    6. num=num+1
    7. print'----按name查cookie:',dr.get_cookie("PSTM")#通过cookie的name获取cookie信息
    8. dr.add_cookie({'name':'hello','value':'123456789'})#向name和value添加会话信息
    9. cookies2=dr.get_cookies()#重新获取cookie的所有信息
    10. for ck2 in cookies2:
    11. if ck2['name']=='hello':
    12. print"----加入的cookie信息:%s-->%s",(ck2['name'],ck2['value'])
    十五、javascript调用,python使用的方法:execute_script()
    python代码:
    1. dr.get("http://www.baidu.com")
    2. dr.find_element_by_id("kw").send_keys("selenium")
    3. dr.find_element_by_id("su").click()
    4. js="var q=document.documentElement.scrollTop=1000"    #滚动条滚到最下面
    5. dr.execute_script(js)
    6. time.sleep(4)
    7. js2="var q=document.documentElement.scrollTop=0"      #滚动条滚到页面顶
    8. dr.execute_script(js2)
    十六、截图,适用于脚本出错时,对当前窗口进行截图保存,使用函数:get_screenshot_as_file()
    python代码:
    1. dr.get("http://www.baidu.com")
    2. try:
    3. dr.find_element_by_id("kw1").send_keys("selenium")
    4. dr.find_element_by_id("su").click()
    5. exceptNoSuchElementException,msg:
    6. dr.get_screenshot_as_file("d:\error.jpg")    #截图输出到d盘
    7. print msg
    8. dr.close()
    十七、关闭窗口
        quit():退出相关驱动程序并关闭所有窗口。
        close():关闭当前窗口,打给多个窗口时,可使用来关闭当前窗口
    十八、验证码处理
        方法1:去掉验证码,问题:如果是在正式环境跑脚本那么在取掉会存在风险
        方法2:设置万能验证码,不需要取消验证码,在程序中留后门--设置一个万能验证码,输入万能验证码了就标识通过
    python代码: 
    1. import random
    2. randnum=random.randint(1000,9999)
    3. print"----生成随机数为:",randnum
    4. input_num=input(u"请输入验证码:")
    5. print"----输入验证码为:",input_num
    6. if input_num==randnum:
    7. print"随机数正确,登录成功"
    8. elif input_num==1234:
    9. print"输入正确,登录成功"
    10. else:
    11. print"登录失败"
        方法3:使用cookie方法获取,读取之前登录的cookie值访问时,直接登录,不需要验证码





  • 相关阅读:
    超级迷宫我的计划表
    不敢死队
    Let the Balloon Rise
    Hangover
    汉诺塔系列2
    Tri Tiling(递推)
    Tiling(递推,高精度)
    Color Me Less
    I Think I Need a Houseboat(圆计算)
    Kbased Numbers(递推)
  • 原文地址:https://www.cnblogs.com/georgelei/p/4761956.html
Copyright © 2020-2023  润新知