相信你在网上一搜有大把的资料可以查看参考,不乏大佬们的专业讲解,都有很高的参考价值,不过我还是推荐你先看一下官方说明,毕竟这是官方的一手教材:https://www.selenium.dev/documentation/en/;
下面随便写写自己认为重要的地方。
零、 仅首次配置时考虑:下载对应的webdriver放在python编辑器文件目录下,管理台pip isntall selenium
Chrome浏览器驱动下载地址:http://chromedriver.storage.googleapis.com/index.html
Firfox浏览器驱动下载地址:https://github.com/mozilla/geckodriver/releases
IE浏览器驱动下载地址:http://docs.seleniumhq.org/download/
Edge浏览器驱动下载地址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
一、首先从流程上来说,ui自动化的常规步骤大致是以下几点:
1. 建立连接
from selenium import webdriver
browser=webdriver.Chrome()
browser.get("https://www.zhihu.com/explore")
2. 定位元素(常见查找元素方法定位、切入框架后再定位、切入弹窗复选框等)
2.1 定位元素的几种方式:(元素多个时,element换为elements,列表index确定某个元素)
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
###其中xpath的层级定位和周定位值得关注:###
2.1.1 层级定位
//div[@id="u1"]//a[@name="tj_login"]
2.1.2 轴定位
# 表达式 /轴定位名称::标签名[属性表达]
# 兄弟姐妹 - 直系的 有比你大的,有比你小的。
# preceding-sibling: 哥哥姐姐
# following-sibling:弟弟妹妹
//a[@name="tj_trvideo"]/following-sibling::a[@name="tj_login"]
//a[@name="tj_settingicon"]/preceding-sibling::a[@name="tj_login"]
# 爸爸:parent 祖先:ancestor
//a[@name="tj_trtieba"]/parent::div/a[@name="tj_login"]
//a[text()="百度首页"]/parent::div/following-sibling::div//a[@name="tj_login"]
2.2 切iframe
switch_to.frame(parameter)
这里的参数可以传入id、name、index以及selenium的WebElement对象
2.3 切入弹框
alert = driver.switch_to.alert #切到弹出框
print(alert.text)
alert.accept() #确定 取消为 alert.dismiss()
2.4 复选框
checkboxes = driver.find_elements_by_xpath("//*[@id='phone-form']//input[@type='checkbox']")
count = 0
if checkboxes: # 判断是否有找到元素
for checkbox in checkboxes: # 循环点击找到的元素
checkbox.click() # 勾选复选框
count += 1
print("打印信息 ", count)
time.sleep(2)
else:
print("没有找到元素")
3. 对元素进行操作(输入、点击、表单提交、模拟鼠标键盘动作等)
3.1 输入点击提交
input=browser.find_element_by_id("aaa")
input.send_keys("沈一楞")
button=browser.find_element_by_class_name("btn-search")
button.click()
WebElement login= driver.findElement(By.id(“loginBtn”));
login. submit() # 用在表单提交
3.2 行为链示例
from selenium.webdriver import ActionChains
#确定拖拽目标的起点
source=browser.find_element_by_id("draggable")
#确定拖拽目标的终点
target=browser.find_element_by_id("droppable")
#形成动作链对象
actions=ActionChains(browser)
actions.drag_and_drop(source,target)
#---------------执行显示--------------------#
actions.perform()
#切换到alert弹出框上
t=browser.switch_to_alert()
print(t.text)
t.accept()
time.sleep(10)
browser.close()
3.3 行为链方法:
click(on_element=None) ——单击鼠标左键
click_and_hold(on_element=None) ——点击鼠标左键,不松开
context_click(on_element=None) ——点击鼠标右键
double_click(on_element=None) ——双击鼠标左键
drag_and_drop(source, target) ——拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
key_down(value, element=None) ——按下某个键盘上的键
key_up(value, element=None) ——松开某个键
move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
move_to_element(to_element) ——鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置
perform() ——执行链中的所有动作
release(on_element=None) ——在某个元素位置松开鼠标左键
send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素
4. 断言
4.1 三种类型,"assert" "verify" 和"waitFor".
4.2 assert
assertEqual(a,b,[msg='测试失败时打印的信息']): 断言a和b是否相等,相等则测试用例通过。
assertNotEqual(a,b,[msg='测试失败时打印的信息']): 断言a和b是否相等,不相等则测试用例通过。
assertTrue(x,[msg='测试失败时打印的信息']): 断言x是否True,是True则测试用例通过。
assertFalse(x,[msg='测试失败时打印的信息']): 断言x是否False,是False则测试用例通过。
assertIs(a,b,[msg='测试失败时打印的信息']): 断言a是否是b,是则测试用例通过。
assertNotIs(a,b,[msg='测试失败时打印的信息']): 断言a是否是b,不是则测试用例通过。
assertIsNone(x,[msg='测试失败时打印的信息']): 断言x是否None,是None则测试用例通过。
assertIsNotNone(x,[msg='测试失败时打印的信息']): 断言x是否None,不是None则测试用例通过。
assertIn(a,b,[msg='测试失败时打印的信息']): 断言a是否在b中,在b中则测试用例通过。
assertNotIn(a,b,[msg='测试失败时打印的信息']): 断言a是否在b中,不在b中则测试用例通过。
assertIsInstance(a,b,[msg='测试失败时打印的信息']): 断言a是是b的一个实例,是则测试用例通过。
assertNotIsInstance(a,b,[msg='测试失败时打印的信息']): 断言a是是b的一个实例,不是则测试用例通过。
比如:
self.assertEqual(u"123_百度搜索",driver.title)
self.assertFalse(driver.title)
self.assertTrue(driver.title)
4.3 其他在意的地方:
logo=browser.find_element_by_id("aaa")
print(logo.text)# 文本内容
print(logo.get_attribute("class"))# 对应属性
#id
print(logo.id)
#位置
print(logo.location)
#标签名
print(logo.tag_name)
#大小
print(logo.size)
****************************************************************************
text()方法可以获取单个元素的链接文本
如果想要列表里的全部元素的链接文本,可以使用get_attribute()方法;eg:
element.get_attribute("class")
element.get_attribute("href")
elemnet.get_attribute("date-url")
*****************************************************************************
5. 关闭连接
browser.close()
二、通用编程习惯:通用的重要关注点;
比如:窗口最大化;切换句柄;强制、显式和隐式等待;浏览器的前进后退;cookie的处理等;
1. 窗口最大化
bro.maximize_window()
2. 切换句柄
current_handle = bro.current_window_handle #获取当前页面句柄
handles = bro.window_handles #获取所有的页面句柄
for handle in handles:
if current_handle!=handles[0]:#若页面句柄不等于第一个句柄,即相当于此时句柄未刷新还是旧的
bro.switch_to_window(handles[0])
3. 没必要的话,比如没有页面跳转,尽量不用强制等待,浪费时间性能;工作中,一些页面跳转时,显式和隐式等待效果不太好时,可以考虑强制等待1秒。
实际工作中常用隐式等待,因为简单。。。。
3.1 强制等待:time.sleep()
3.2 显示等待; 等待---直到参数或函数出现期待的结果
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser=webdriver.Chrome()
url="https://www.taobao.com"
browser.get(url)
wait=WebDriverWait(browser,10)
input=wait.until(EC.presence_of_element_located((By.ID,"q")))
button=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn-search")))
print(input,button)
browser.close()
3.3 隐式等待:为浏览器对象创建一个等待时间,实际上浏览器会在你自己设定的时间内部断的刷新页面去寻找我们需要的元素;
如果webdriver没有在DOM中找到元素,将继续等待,超过设定的时间后则抛出找不到元素的异常;
# -*- coding: utf-8 -*-
from selenium import webdriver
browser=webdriver.Chrome()
url="https://www.zhihu.com/explore"
browser.get(url)
browser.implicitly_wait(10)
logo=browser.find_element_by_id("zh-top-link-logo")
print(logo)
browser.close()
4. 前进和后退
browser=webdriver.Chrome()
browser.get("https://www.taobao.com")
browser.get("https://www.baidu.com")
browser.get("https://www.python.org")
browser.back()
time.sleep(1)
browser.forward()
browser.close()
5. cookie处理
browser=webdriver.Chrome()
browser.get("https://www.zhihu.com/explore")
print(browser.get_cookies())
browser.add_cookie({"name":"name","domain":"www.zhihu.com","value":"germey"})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())
browser.close()
三、框架习惯:
1. python+ selenium webdriver
2. 常用函数封装,重复性比较多的地方都可以进行封装,比如ui自动化开头通用的:拿driver、进url、窗口最大化、切最新句柄;这一套可以封装在一起,之类的。
3. 异常处理:好的代码结构:
try:
browser.find_element_by_id("hello")
except NoSuchElementException:
print("No Element")
finally:
browser.close()
四、扩展
1. 隐式等待和显式等待的优缺点:
隐式等待:
隐式等待结束的标志:
1、页面全部加载完成。
2、设置的等待时间截止。
隐式等待本身不会产生任何报错,但超时之后,容易产生NoSuchElementException的异常。
在python中,通过driver.implicitly_wait() ,设置隐式等待。
优点:
不用频繁进行等待的添加,一次添加终生有效,不会浪费过多的时间在等待中。
缺点:
但可能页面加载未完成的时候,需要定位的元素已经加载完成了,但受限于某些JS文件、图片加载特别慢,我们不能执行下一步,必须得等到网页所有东西都加载完了才能下一步【增加不必要的加载时间】
显式等待:
对指定元素进行等待的一种等待方式,通过设置最大等待时间,检查频率对页面的元素来进行等待,一旦找到该元素,则停止等待,进入后续步骤,显示等待分为Untill和Untill_Not两种方式,Untill就是当条件为真,则进行后续操作,Untill_Not则相反。当最大等待时间达到,却依旧未找到元素,则会报TimeoutException异常。
在python中是基于selenium.webdriver.support.wait导入WebDriver来实现。
优点:
1、可以直接对元素进行定位,花费最少的时间来实现整个流程。
2、可以用于作为断言的检验之一。
缺点:
1、条件过于复杂
2、和强制等待类似,每行等待只执行一次,如果要进行过个元素的等待,则需要多次写入。