基于selenium的web自动化学习之路总结(二)--Python+元素定位

导语

        本次通过执行业务修改个人资料,来记录在编写脚本时遇到的问题及解决方式,具体业务为:登录商城-->点击账号设置-->点击个人资料-->修改真实姓名-->选择性别-->选择生日-->输入QQ-->点击确认按钮。

一、submit按钮难以定位

        在上一篇文章中基于selenium的web自动化学习之路总结(一)有讲到登录的定位方式,假如这里的“登录”按钮,使用常用的定位方式无法定位,这时候我们可以采用submit方法。

图1 登录

         仔细看一下登录的html,会发现这其实是个表单,而submit方法,类似click,只能用于form表单中,在form表单中,所有数据一起提交,提交任何一个元素,就提交了整个表单。代码如下:

# 输入用户名、密码
chromedriver.find_element_by_id("username").send_keys("xiao")
chromedriver.find_element_by_id("password").send_keys("123456")
# submit方法来定位登录按钮并点击的操作
chromedriver.find_element_by_id("password").submit()

二、部分链接定位使用方法

图2 个人资料

        可以注意到,“个人资料”前面还有个小图标,如果“个人资料”被图标隔断呢,这个时候就可以使用部分链接文本来定位,代码如下:

# 点击个人资料
chromedriver.find_element_by_partial_link_text("人资").click()

三、css_selector  用法二

图3 性别单选按钮

         在上一篇文章中基于selenium的web自动化学习之路总结(一)有讲到css_selector的一种用法,这里介绍第二种用法,观察HTML发现,性别这里的三个单选按钮,只有value属性不同,其他属性都一样,这样可以使用css_selector的另一种用法,可以采用任意的属性来定位元素,只需要在属性两边加一对中括号,代码如下:

# 选择性别
chromedriver.find_element_by_css_selector("[value='2']").click()

四、处理日历控件

4.1 定位日历控件的方法

图4 日历控件原HTML

        日历控件的定位,可以一次一次的点击,去选择年月日,但是过于繁琐。通过观察发现(图4),这个日历控件input type="text" ,本质也是文本类型的输入框,只是后面还有一个readonly,只读。尝试在HTML中将这个readonly删掉后就会发现(图5),这个文本框就可以输入了,这样就有了一个想法,是不是可以想办法删除readonly属性,再去向日历控件中输入生日?

图5 日历控件删除readonly

         但是,selenium无法删除一个元素的属性,JavaScript可以做到,先在控制台尝试操作一下,输入以下内容:

        document.getElementById("date")

        document.getElementById("date").removeAttribute("readonly")

图6 控制台操作删除readonly

         这样一来,我们只需要将此方法转换到Python中,便可以达到想要的效果了,代码如下:

# 删除readonly属性
script = 'document.getElementById("date").removeAttribute("readonly")'
chromedriver.execute_script(script)
# 输入新生日
chromedriver.find_element_by_id("date").send_keys("1999-01-01")

        执行程序后,发现选择生日的问题解决了,但是,程序多次执行后,又发现了新的问题。

4.2 问题--旧数据与新数据并存

图7 衍生问题1

         按照我们功能测试的经验,一般是先删除旧数据,再写入新数据,代码也可以如此操作,代码如下:

# 清除旧生日
chromedriver.find_element_by_id("date").clear()
# 输入新生日
chromedriver.find_element_by_id("date").send_keys("1999-01-01")

        接下来的业务是输入 QQ,点击“确认”按钮,均可以采用常用定位方式解决,但是在多次执行程序后,“真实姓名”和“QQ”输入框均会出现上述的旧数据与新数据并存的问题,也可以在每一个send_keys的操作前加入clear操作,当然这样重复的代码是有优化方案的,在本次就不多说啦。

五、处理弹出框

5.1弹出框分析

图8 弹出框

        弹出框alert,不是HTML的页面元素,而是JavaScript的控件,由于不能通过右键-检查来查看,所以不同于传统的方法操作,selenium提供了三个常用处理alert的方法:

        (1)点击确定按钮:driver.switch_to.alert.accept()

        (2)点击取消按钮:driver.switch_to.alert.dismiss()

        (3)获取弹出框提示的文本信息:driver.switch_to.alert.text

        在这里,用第一种方式来操作一下,代码如下:

# 点击确定,关闭弹出窗
chromedriver.switch_to.alert.accept()

5.2 时间等待问题分析

        执行上述代码后,会发现网页中弹出窗的确定按钮并没有被点击,因此弹出窗没有关闭,查看代码,发现已经报错,报错如下:

图9 关闭弹出窗代码报错

        程序执行的时候发现没有这个弹出框,这是什么原因呢,明明我们在页面中可以看到弹出框。再执行一次代码,发现弹出框的出现可能存在延迟,但是回顾代码发现,已经加入了隐式等待,代码如下 :

chromedriver = webdriver.Chrome()
chromedriver.implicitly_wait(5)

        这里说明一下,在处理弹出框时,隐式等待不起作用,因为隐式等待判断的是页面的加载,点击确定按钮,弹出框出来后,页面没有刷新过,所以不会起作用,这样在处理弹出框前,加一个强制等待时间即可,代码如下:

# 关闭弹窗
time.sleep(3)
chromedriver.switch_to.alert.accept()

        加入了时间等待后,果然可以正确执行,关闭弹出窗了,但是这样,可能很多时候不需要3秒,那有没有智能的方式呢?还有一种显示等待方式,代码如下:

# 关闭弹窗
WebDriverWait(chromedriver, 30, 0.5).until(expected_conditions.alert_is_present())
chromedriver.switch_to.alert.accept()

        简单解释一下这个显示等待,针对chromedriver最长等待时间30s,每隔0.5s检查一下,如果弹出框已经出现,则不用再等待,如果没有找到弹出框,就隔0.5s检查一下,直到找到弹出框为止。

        总结一下,目前已经使用过3种时间等待方式:

        (1)强制等待:time.sleep(3)

        (2)隐式等待:chromedriver.implicitly_wait(3)

        (3)显示等待:WebDriverWait(chromedriver,30,0.5).until(expected_conditions.alert_is_present())  ,expected_conditions后有多种方式,根据需要选择即可。

六、总结

        本次说明了submit方法、partial_link_text、css_selector的用法,并分析了日历控件和弹出框的处理方式,同时发现了时间等待的问题。

        成长之路,道阻且长,后续会继续总结自己平时遇到的一些问题,加油!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值