Webdriver(selenium2)基于Python脚本实现登录填写日志(分步讲解)

webdriver的API为我们做web自动化测试提供了强大支持,以下是本人完成该环境下的第一个脚本,时间用了蛮久,过程中在书本和网上查了很多信息,但是都没有根据脚本比对前端页面代码的讲解,于是详细记录了自己遇到的坑和解决办法,希望能给他人提供那么一点点的帮助,有问题也希望可以提出一起进步。

首先是登陆页面

# coding=utf-8
'''
脚本内容:完成登录日志系统,填写日志等操作
完成时间:2017-05-22
制作人:Tyrion Von
环境:webdriver()
'''
#分别导入webdriver的包、使用keys的包和控制“等候时间”的包
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

#引入webdriver自带的firefox驱动并登录系统
a = webdriver.Firefox()
a.get("目标页面的URL")
#我用的是公司url,请谨慎调戏,不然会爆炸,谢谢
time.sleep(2)

# 填写用户名&密码
a.find_element_by_name("userid").send_keys('用户名')
time.sleep(1)
a.find_element_by_name("userpwd").send_keys('密码')

# 定位密码框,用回车键替代登陆按钮
a.find_element_by_name("userpwd").send_keys(Keys.ENTER)
print('Good start!')
time.sleep(8)#睡眠时间不足,会导致定位不到需要的页面元素

上面这几步完成了登陆,分步解析:

1.根据name定位输入user/pwd的窗口;
webdriver提供了8种定位web页面元素的方法,网上有很多介绍,这里就不再详述,每一种都试过之后,本人认为最有效的就是通过xpath和css定位,如果页面结构比较规范的,也可以考虑用find_element_by_name或者by_id,具体情况具体分析,感兴趣的朋友可以挨个试试。
2.提交录入的内容;
这里定位“登录”按钮设置点击事件时,老是定位不到,后面感觉可能是因为没有考虑到一些细节(可能要先定位框架…),后来发现可以通过回车直接提交,就略过了这个问题,感兴趣可以研究下;
3.每个操作后设置等待时间;
为什么每一步操作都尽可能需要设置“等待时间”?因为跳转页面时,下一个页面还在读取,如果没有等待时间,会导致下一步的操作读取不到,听说有直接等待页面跳转完毕再进行下一步的方法,该方法应该更科学,感兴趣可以试试;

通过浏览器自带的开发工具来定位页面元素、提取Xpath

登陆后的页面结构

可以看到,在登陆后的页面,“导航部分”的“日志周报”按钮,就是我们需要点击的部分了:

当初在这里卡了很长时间,一直定位不了,不论是使用by_xpath()还是直接用find_element_by_link_text(),都不能定位,然后试了所有定位方法都不行,有一种血崩的感觉,后面想找一个fiddler来抓包看下网页跳转的过程中到底发生了什么导致定位不了,"跳转"两个字给了自己灵感,然后重新检查页面,才发现跳转过后的前端页面上有新的框架,定位元素需要首先定位框架。同理,如果有新的窗口弹出,应该先定位新的窗口,详情百度switch_to.window()

下面是登陆后的脚本内容:
"""
定位到新的页面0,这个根据页面代码选择是switch_window还是switch.frame
a.switch_to_window(a.window_handles[0])
接下来非常重要,登陆后发生页面跳转,定位到新的框架,这里的参数应填写页面frame中包含的id
"""
a.switch_to.frame("topFrame")
"""
定位到新的窗口sreach_window = a.current_window_handle
点击进入“日志周报”模块
"""
a.find_element_by_link_text('日志周报').click()
print('Almost There!!')
#或者用a.find_element_by_xpath('//*/td[2]/a/b').click()

点击“日志周报”事件之后,左侧产生了另一个frame

可以看到左侧产生的frame中, 出现了2个按钮,此时如果直接定位“日志管理”,会出现exception定位不到,常用的方法是通过switch_to.parent_frame()方法,返回上一级frame,然后根据目标frame的id重新进入:

"""
返回上一级框架后,进入左侧框架
"""
a.switch_to.parent_frame()

# 下一步,准备进入“日志管理”模块
time.sleep(3)

# 非常重要,发生第二次页面跳转,定位到新的框架,这里的参数应填写页面frame中包含的id
'''
可以根据frame的ID来定义一个变量,然后进入这个框架即可
frame = a.find_element_by_id('leftFrame')
a.switch_to.frame(frame)
'''
# 或者直接根据frame的ID进入
a.switch_to.frame("leftFrame")
print('Keep goin!!')
# a.switch_to.frame('left')--注意:不能指定一个frameset来作为跳转目标

# 点击frame下的“日志管理”模块
a.find_element_by_xpath('//*[@id="container"]/div/ul/li[1]/a/div').click()
time.sleep(6)#睡眠时间不足,会导致定位不到需要的页面元素

到这里页面发生了第三次跳转,页面好像又要产生frame了:
这里写图片描述
有吗?还真有。frame id=”mainframe”,这时候我们要定位“新增”按钮:
这里写图片描述
代码如下:

"""
此时页面产生了新的框架,需要进入父级frame后,重新进入目标按钮所在的mainframe,实现点击事件
"""
a.switch_to.parent_frame()
a.switch_to.frame("mainframe")
print('Is this it?')
a.find_element_by_xpath('//*[@id="dayInfo!list"]/table[3]/tbody/tr/td[3]/input[1]').click()

点击“新增”按钮之后,可以预见会产生一个新的窗口,应如何定位新窗口呢?
新增窗口

前面提到了switch_to.window()方法,根据窗口的句柄,利用一个for循环可定位新窗口:

"""
打印当前句柄&定义当前所有句柄
"""
print (a.current_window_handle)
first_window = a.current_window_handle
all_handles = a.window_handles
print (all_handles)

# 使用for循环+if判断,排除第一个个窗口,切换到新窗口
for handle_2 in all_handles:
    if handle_2 != first_window:
        print('switch to,' + handle_2)
        a.switch_to.window(handle_2)
        print('handle_2 = ' + handle_2 + ',first_window = ' + first_window)
time.sleep(5)

完成新窗口定位以后,下一步就要定位新窗口的页面元素。此时已经比较熟练了,先看有无frame,而后再定位实现页面操作。

"""
新窗口中出现了一个小坑iframe,呵呵
"""
frame_3 = a.find_element_by_xpath("/html/body/iframe")
a.switch_to.frame(frame_3)
time.sleep(5)
print("Very close!")

定位完成之后,在窗口中完成一系列必要的录入,提交并结束:

"""
a.find_element_by_xpath('//*[@id="prjName"]').click()
time.sleep(2)
这段是点击下拉按钮,后来发现可以不点这个按钮也能触发下拉选项中的点击事件
"""
a.find_element_by_xpath('//*[@id="prjName"]')
#选择之前要重新定位下来框的位置,否则无法执行下一步下拉选项中的点击事件
a.find_element_by_xpath('//*[@id="prjName"]/option[3]').click()
time.sleep(5)

# 填写工时&任务内容
a.find_element_by_xpath('//tbody/tr[2]/td[6]/div/input').send_keys('8')
a.find_element_by_xpath('//*[@id="Taskdescription"]').send_keys('熟悉需求,完善LIDO模块的测试用例')
time.sleep(5)

# 填写完毕,点“确定”完成提交
a.find_element_by_xpath('//*[@name="ok"]').click()
print('Congrates')
time.sleep(5)

# 结束,关闭页面
a.quit()

跑脚本结果

总结

一、整个过程难点在于两个:
1.如果页面上有frame需要先定位frame而后再定位元素,没弄过不一定知道,一直报“cannont locate”,容易耗比较多时间在这里;
2.通过句柄切换新窗口,根据for循环是比较好用的办法,应该还有其他办法也可以实现。在此之上,还有返回上一个窗口等方法。
二、定位元素就是熟能生巧了,用多了就知道哪些方法更不容易报错。
三、过程中涉及到一些前端HTML/CSS的知识,感兴趣可顺便了解下

Tips:

1.通过Chrome自带的调试工具可以快捷copy页面元素的xpath,节省时间减少错误;
2.睡眠时间太短会导致定位不了跳转后的页面元素;
3.调试的时候,可以在每个节点设置print一些字符,便于检查错误;
4.觉得还行的话求顶,或者留言批评我,跪求^_^。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值