自动化测试记录
隐式等待
wb.implicitly_wait(5)
implicitly_wait(xx),隐性等待的意义是:闪电侠和凹凸曼约定好,不论闪电侠去哪儿,都要等凹凸曼xx秒,如果凹凸曼在这段时间内来了,则俩人立即出发去打怪兽,如果凹凸曼在规定时间内没到,则闪电侠自己去,那自然就等着凹凸曼给你抛异常吧。
强制等待
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get('https://huilansame.github.io')
sleep(3) # 强制等待3秒再执行下一步
print driver.current_url
driver.quit()
最简单粗暴的一种办法就是强制等待sleep(xx),强制让闪电侠等xx时间,不管凹凸曼能不能跟上速度,还是已经提前到了,都必须等xx时间。
这种叫强制等待,不管你浏览器是否加载完了,程序都得等待3秒,3秒一到,继续执行下面的代码,作为调试很有用,有时候也可以在代码里这样等待,不过不建议总用这种等待方式,太死板,严重影响程序执行速度。
切换iframe窗口
wb.switch_to.frame('iframe1') # 切换窗口
# wd.switch_to.frame(frame_reference)
# 其中, frame_reference 可以是 frame 元素的属性 name 或者 ID 。
# 比如这里,就可以填写 iframe元素的id ‘frame1’ 或者 name属性值 ‘innerFrame’。
handle 句柄
selenium遇到无法定位元素解决方法,首先判定是不是alert,再判定是不是iframe,如果都不能解决就使用selenium的handle处理方式再进行定位操作:
# 打印全部的handle
all_handle = driver.window_handles
#打印当前的handle
handle = driver.current_window_handle
# 切换到新的handle上
driver.switch_to.window(handle)
selenium中的三大切换(handle窗口、iframe切换、alert弹框)
handle窗口切换
一、handle窗口切换
当点击某个元素后,会重新生成一个新的页签,但此时我们的操作仍然在原先的窗口当中,如果要在新的窗口继续操作元素,那么就要用到handle窗口切换的方法。
常用方法:
window_handles:获取当前打开的所有窗口句柄,返回类型为一个列表。
current_window_handle:获取当前窗口的句柄。
switch_to.window(handle_path):切换窗口,handle_path参数代表的是一个窗口句柄。
当操作某个元素后需要等待新的元素出现,我们用到了显性等待,EC给了我们一个方法为visibility_of_element_located(),表示元素可见,那么在handle窗口切换时也涉及到等待,那就是等待新的窗口打开,我将用一般方法和新的方法来展示,具体用法如下:
(使用time.sleep()强制等待):
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.maximize_window()
driver.find_element_by_id("kw").send_keys("python")
driver.find_element_by_id("su").click()
loc = (By.XPATH, "//a[text()=' 基础教程 | 菜鸟教程']")
WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc))
driver.find_element(*loc).click() # 点击后新的窗口出现
# 切换到新的窗口,在新窗口去操作元素
time.sleep(1) # 强制等待1秒
# 1、获取当前打开的所有窗口。--- 窗口列表。handles
wins = driver.window_handles
print(wins)
# 打印打前窗口的句柄
print(driver.current_window_handle)
# 2、切换的语句 ,切换到你想操作元素所在的窗口。进入到了新的html页面 - 新的窗口 wins[-1]
driver.switch_to.window(wins[-1])
# 3、在新的页面当中,找元素,并操作
loc = (By.XPATH, "//ul[@class='pc-nav']//a[text()='首页']")
WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc))
driver.find_element(*loc).click()
iframe 切换
二、iframe切换
iframe表示在主html上嵌入的子html页面如下图所示:
当我们要在新的html页面操作元素,就要切换到新的html页面后才能进行接下来的操作,常用方法如下:
switch_to.frame(path):切换到新的html页面,path支持下标、name、WebElement对象三种参数
switch_to.default_content():切换到主html页面
switch_to.parent_frame():切换到上一层html页面(父页面)
在iframe切换中也有等待,除了使用time.sleep()方法外,EC给了我们一个方法为frame_to_be_available_and_switch_to_it(),表示iframe有效并切换到iframe当中,它支持下标、name、WebElement对象以及元组四种方法传参。
alert弹窗切换
三、alert弹框切换
如何区分是alert弹框呢?一个简单的方法就是无法使用元素定位的弹框,并且需要优先处理后才能操作后面的元素,常用方法如下:
switch_to.alert:切换到alert弹框
accept():确定
dismiss():取消
send_keys(keysToSend) :输入文本,keysToSend表示输入的文本内容字符串
text():获取弹出框里面的内容
在EC里面也给alert弹框设定了一个方法,alert_is_present()方法表示等待alert弹框出现并切换到alert弹框中
方法一(常规做法):
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("http://XXXX")
# 做一个操作,导致alert框出现
driver.find_element_by_id("idxxx").click()
# 切换到alert弹框
alert = driver.switch_to.alert
# 获取alert的文本内容
print(alert.text)
# 点击确定,关闭弹框
alert.accept()
方法二(使用骚操作EC.alert_is_present()方法):
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("http://XXXX")
# 做一个操作,导致alert框出现
driver.find_element_by_id("idxxx").click()
# EC条件 -- 等待alert弹框出现,并切换到alert当中
alert = WebDriverWait(driver, 10).until(EC.alert_is_present())
# 获取alert的文本内容
print(alert.text)
# 点击确定,关闭弹框
alert.accept()
HTML注释
注释标签 用于在 HTML 插入注释。
切换窗口
mainWindow = wb.current_window_handle
wb.switch_to.window(mainWindow)
--------------------
for handle in wb.window_handles:
wb.switch_to.window(handle)
print(wb.title)
下拉单选框
from selenium.webdriver.support.ui import Select # 导入Select类
select = Select(wb.find_element_by_xpath('//*@id="formobj"]/table/tbody/tr[2]/td[4]/select'))
# 创建Select对象
select.select_by_visible_text('城区+村镇') #根据选项的 可见文本 ,选择元素。
select.select_by_index() #根据选项的 次序 (从0开始),选择元素
select.select_by_value() #根据选项的 value属性值 ,选择元素。
PIL模块安装
D:develop_studypythonPytho38-32>pip install Pillow
图片验证码识别
首先得装环境,识别验证码已经不是selenium自己能办到的了。cmd下输入下面命令:
pip install Pillow(如果报错,输入:pip.exe install Pillow)
pip install pytesseract(如果报错,输入:pip.exe install pytesseract)
第一个是对图片处理的包,第二个是识别验证码的包,还需要下载个包,百度搜索:Tesseract-OCR,下载解压到电脑,可以不放在C盘,这个好像也没有位数限制。
解压到电脑以后需要加上环境变量,在path里加上Tesseract-OCR的路径,然后在pycharm里(我只用这个,别的工具什么情况我不知道),External Libraries->Python 3.x->Lib->site-packages->pytesseract->pytesseract.py里面修改一段代码:
————————————————
由于斜杠是转义字符,我就用了双斜杠,一定要看清不是只加到环境变量的那个路径,后面要加到tesseract.exe,我只记得这一个坑,执行脚本总是提示我未安装或者没配置环境变量。准备工作就这么多,下面我放上我的代码,供参考。
验证码登陆
from selenium import webdriver
import time
from PIL import Image
import pytesseract
import re
wb = webdriver.Chrome(r'D:develop_studychromedriverchromedriver')
wb.get('http://192.168.10.233:8080/marsCloud/loginController.do?login')
wb.maximize_window()
wb.implicitly_wait(5)
wb.find_element_by_id('userName').send_keys('admin')
wb.find_element_by_id('password').send_keys('123456')
wb.save_screenshot('D:\security_code\printscreen.png') # 截屏
imgelement = wb.find_element_by_id('randCodeImage') # 定位验证码
location = imgelement.location # 获取验证码x,y坐标
print(location)
size = imgelement.size # 验证码高度、宽度、
print(size)
left = int(location['x']+246)
top = int(location['y']+75)
right = int(location['x']+size['width']+263)
bottom = int(location['y']+size['height']+83)
img = Image.open('D:\security_code\printscreen.png').crop((left,top,right,bottom)) #打开截图
img2 = img.convert('RGB')
img2.save('D:\security_code\save.png')
code = pytesseract.image_to_string(Image.open('D:\security_code\save.png'))
print(code.strip())
# 正则表达式去除空格或其他特殊符号
b=''
for i in code.strip():
pattern = re.compile(r'[a-zA-Z0-9]')
m = pattern.search(i)
if m!=None:
b+=i
#输出去特殊符号以后的验证码
print (b)
wb.find_element_by_id('randCode').send_keys(b)
wb.find_element_by_id('but_login').click()
#
# cookie = wb.get_cookies()
# print(cookie)
词云
pip install wordcloud
iframe切换失效修正
xck = wb.find_element_by_xpath('/html/body/div[2]/table/tbody/tr[2]/td[2]/div/table/tbody/tr[2]/td[2]/div/iframe')
# xpath 定位到新窗口对应iframe
wb.switch_to.frame(xck) # 切换到新窗口 iframe
iframe = driver.find_elements_by_tag_name("iframe")[0]
driver.switch_to.frame(iframe) (较新版本推荐使用方法)
2、单据列表选择