@python+selenium学习笔记
单纯的记录一下自己在用Selenium写公司的小程序后台UI自动化测试脚本中遇到的问题,方便以后温习。
1.登陆页面的验证码
(1)最开始是打算尝试对验证码进行截图后图像处理,识别出其中的数字,但是因为图片底部的干扰项,最终失败告终,后面退一步采取了手动输入验证码的方式。但是还是将尝试过程的代码粘贴出来,主要涉及整个页面的截图保存后对截图中的验证码进行截取,然后对验证码截图进行图像处理,此处记录或许对以后相关方面的学习有用处。
首先要https://github.com/UB-Mannheim/tesseract/wik中下载 tesseract-ocr,安装,然后就可以操作了
代码如下:
# 指定ocr的安装目录
pytesseract.tesseract_cmd = ('D:\\tesseract\\Tesseract-OCR\\tesseract.exe')
# 验证图片元素
imgElement = 'D:\\photo\\captcha.png'
# 截取屏幕内容,保存到本地
print("截取屏幕内容,保存到本地")
driver.save_screenshot("D:\\photo\\captcha.png")
# 打开截图,获取验证码位置,截取保存验证码
ran = Image.open("D:\\photo\\captcha.png")
imgelement = driver.find_element_by_xpath("//*[@id='LAY-user-login']/div/div[2]/div[3]/div[2]/img") # 定位验证码
left = imgelement.location['x']#获取验证最左边位置
top = imgelement.location['y']#获取验证码上边位置
right = left + imgelement.size['width']#获取验证码右边位置
bottom = top + imgelement.size['height']#获取验证码下边位置
open_img = Image.open('D:\\photo\\captcha.png')#打开屏幕截图
box = open_img.crop((left, top, right, bottom))#使用获取到的位置剪切图片
print("使用获取到的位置剪切图片")
box.save('D:\\photo\\2captcha.png') # 保存我们接下来的验证码图片 进行打码
# 4、获取验证码图片,读取验证码
imageCode = Image.open("D:\\photo\\2captcha.png") # 图像增强,二值化
imageCode = Image.open(r"D:\\photo\\2captcha.png")
imgry = imageCode.convert('L') #图像加强,二值化,PIL中有九种不同模式。分别为1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。L为灰度图像
sharpness =ImageEnhance.Contrast(imgry)#对比度增强
i3 = sharpness.enhance(3.0) #3.0为图像的饱和度
i3.save("D:\\photo\\3captcha.png")
i4 = Image.open("D:\\photo\\3captcha.png")
code = pytesseract.image_to_string(i4).strip() # 使用image_to_string识别验证码
经过截取、图像处理过的图片
最终在试别数字时失败。
(2)手动输入验证码
代码如下:
# 验证码输入框元素
codeElement = driver.find_element_by_xpath("//*[@id='LAY-user-login']/div/div[2]/div[3]/div[1]/input")
man_code = input("请输入验证码:")
codeElement.send_keys(man_code)
print("验证码填写完成")
2.获取frame中的元素
当在定位元素的时候,确保了xpath准确性的情况下还是定位不到元素,通过浏览器控制台,查看元素源代码,往上看,如果有iframe,证明元素在一个frame表单嵌套的结构里面,需要先切换表单,再定位需要的元素。
如果iframe有id或者name,可通过id或name直接切换表单
driver.switch_to.frame(id)
driver.switch_to.frame(name)
但是我这段源代码中iframe没有id属性和name属性,则需要先定位iframe,再切换表单
# 定位iframe
xf = driver.find_element_by_xpath("//*[@id='LAY_app_body']/div[2]/iframe")
# 切换iframe
x_frame = driver.switch_to.frame(xf)
3.下拉表单
(1)WebDriver提供Select类处理下拉标签
# 搜索结果显示条数
sel = driver.find_element_by_xpath("//select[@id='nr']")
Select(sel).select_by_value('50') # 显示50条
Select类只用于定位select标签。
(2)我遇到的不是select标签,处理办法是通过定位下拉框中的下拉箭头并进行点击操作,展开下拉框后又对目标选项进行定位点击即可。
代码如下:
# 下拉框箭头元素
payment_stutes = driver.find_element_by_xpath("//*[@id='content']/div[1]/div/div/div[12]/div/div/span/span/i")
# 点击下拉框箭头元素
payment_stutes.click()
# 已付款元素
payment_finish = driver.find_element_by_xpath("/html/body/div[2]/div[1]/div[1]/ul/li[2]/span")
# 点击已付款元素
payment_finish.click()
结果如下:
4.WebDriver click()与 JavaScript click()区别
我在执行完搜索操作之后,点击一个详情按钮
一开始用的WebDriver click() 执行点击操作
target = driver.find_element_by_xpath("//*[@id='content']/div[2]/div/div[2]/div[3]/table/tbody/tr[19]/td[14]/div/button")
target.click()
报错如下图:
原因是详情按钮被一个不可见的div元素遮挡,无法点击,之后我尝试了 JavaScript click()执行点击操作,操作成功。
target = driver.find_element_by_xpath("//*[@id='content']/div[2]/div/div[2]/div[3]/table/tbody/tr[19]/td[14]/div/button")
driver.execute_script("arguments[0].click();", target)
WebDriver click()与 JavaScript click()区别:
WebDriver:当WebDriver执行点击时,它会尽可能地模拟真实用户使用浏览器时发生的情况。假设你有一个元素A,它是一个按钮,元素B是一个div透明的元素,但完全覆盖了A。WebDriver点击A,因为B覆盖A,如果用户尝试点击A,则B将首先获得事件。A是否最终会获得点击事件取决于B如何处理事件。
JavaScript:现在,用JavaScript来完成A.click()。这种点击方法并不能重现用户尝试点击A时真正发生的事情。JavaScriptclick直接将事件发送给A,而B不会收到任何事件。
5.弹出窗口
弹出框是alert类型:
selenium提供switch_to_alert方法:捕获弹出对话框(可以定位alert、confirm、prompt对话框)
弹出框不是alert类型:
1、弹出框是div层,跟平常一样定位,不用管弹出框
#点击退出按钮
FindElement(self.brower,"classname","btn-exit").click()
#time.sleep(3)
#点击确认按钮(直接定位元素不用管页面的弹出样式,driver.window_handles打印出来的窗口在同一个页面)
FindElement(self.brower, "classname", "pro-btn.btn-2.btn-confirm").click()
2、弹出框是iframe
driver.switch_to.frame(“frame1”)之后进行定位元素
3、弹出内容是嵌入的窗口解决思路:
# 打印所有的handle
all_handles = driver.window_handles
print(all_handles)
# 切换到新的handle上
driver.switch_to.window(all_handles[1])