Python3+Selenium3自动化测试 - 定位并操作元素
- 根据id获取元素并操作
- find_element_by_xpath 定位DOM元素
- find_element_by_css_selector 定位DOM元素
- 模拟操作键盘
- 模拟操作鼠标
- 定位select下拉框
- Selenium常用的方法
- Selenium三种等待方式
- 强制等待
- 隐性等待
- 显性等待
- 总结
根据id获取元素并操作
import time
from selenium import webdriver
from import By
#启动谷歌浏览器,火狐则是webdriver.firefox(),IE则是()
driver = webdriver.Chrome()
#打开百度网址
driver.get("https://www.baidu.com/")
#根据id获取搜索框(id=kw)并在搜索框输入文字
driver.find_element(, 'kw').send_keys('Python3+Selenium3自动化测试')
#点击搜索(id=su),submit也可以提交搜索,相当于回车
driver.find_element(, 'su').click()
time.sleep(3)
#清除搜索框内容(也可以通过find_element_by_id获取id,还有find_element_by_name等等)
driver.find_element_by_id('kw').clear()
driver.find_element(, 'kw').send_keys('Python有多牛')
driver.find_element(, 'su').submit()
time.sleep(3)
find_element_by_xpath 定位DOM元素
重点讲解一下xpath
本人已知的有两种写法:
text = driver.find_element(By.XPATH, '//*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2]').text
print("百度热搜第一的标题是:" + text)
driver.find_element_by_xpath('//*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2]')
解析:表示获取id=hotsearch-content-wrapper元素下第一个li元素下的a元素下第二个span,获取的元素图如下:
如果实在是觉得这种写法有点复杂,不知道如何下手,可以走捷径(谷歌是可以的,其他浏览器没有试过):
F12后选中要定位的元素右击 - Copy - Copy Xpath 他就会自动帮你复制好Xpath 例如://*[@id=“hotsearch-content-wrapper”]/li[1]/a/span[3]
find_element_by_css_selector 定位DOM元素
#根据class定位 可用.XXX也可以用*.XXX
text = driver.find_element_by_css_selector('.hot-refresh-text').text
print(text)
#根据id定位
driver.find_element_by_css_selector('#kw').send_keys('Selenium 有多牛')
#根据属性定位,具体见下图
driver.find_element_by_css_selector('input[type="submit"][class="bg s_btn"]').click()
模拟操作键盘
#额外需引入的包
from selenium.webdriver.common.keys import Keys
driver.find_element(, 'kw').send_keys('Python3+Selenium3自动化测试')
time.sleep(3)
#利用backspace键删除字符串最后一位
driver.find_element(, 'kw').send_keys(Keys.BACK_SPACE)
#追加空格
driver.find_element(, 'kw').send_keys(Keys.SPACE)
#追加文字
driver.find_element(, 'kw').send_keys('?')
time.sleep(1)
driver.find_element(, 'kw').send_keys(Keys.BACK_SPACE)
driver.find_element(, 'kw').send_keys(Keys.BACK_SPACE)
time.sleep(1)
driver.find_element(, 'kw').send_keys('试')
driver.find_element(, 'kw').send_keys(Keys.ENTER)
#Ctrl+A 全选, Ctrl+X 剪切
driver.find_element(, 'kw').send_keys(Keys.CONTROL, 'a')
driver.find_element(, 'kw').send_keys(Keys.CONTROL, 'x')
time.sleep(2)
#打开新网址
driver.get("https://www.hao123.com/")
#Ctrl+V 粘贴 并 搜索
driver.find_element(, 'word').send_keys(Keys.CONTROL, 'v')
driver.find_element(, 'word').submit()
模拟操作鼠标
#额外需引入的包
from selenium.webdriver.common.action_chains import ActionChains
driver.get('https://www.baidu.com/')
#通过find_element_by_xpath定位到百度的两个热搜元素
title1 = driver.find_element_by_xpath('//*[@id="hotsearch-content-wrapper"]/li[1]/a/span[2]')
title2 = driver.find_element_by_xpath('//*[@id="hotsearch-content-wrapper"]/li[2]/a/span[2]')
#利用鼠标悬停事件,让鼠标从标题1移动到标题2
ActionChains(driver).move_to_element(title1).perform()
time.sleep(2)
ActionChains(driver).move_to_element(title2).perform()
#鼠标右击
ActionChains(driver).context_click(title1).perform()
time.sleep(5)
定位select下拉框
ps: 只有是用< select >标签写的下拉框才有用哦。这一段代码没有做个试验,纯粹是记录一下(因为没有找到合适的下拉框做试验)
#额外需引入的包
from selenium.webdriver.support.select import Select
#窗口最大化(试过,如果窗口小了要定位的元素没有显示完整是会报错的)
driver.maximize_window()
#请求带下拉框的界面
driver.get('https://')
sel = driver.find_element(By.XPATH, '//*[@id="iframeResult"]/iframe/select') # 定位下拉框
Select(sel).select_by_value('value1') # 通过value的值进行选定条目
time.sleep(2)
driver.switch_to.alert.accept() # 此处同意警告框提示内容
driver.quit()
Selenium常用的方法
size 获取元素的尺寸
text 获取元素的文本
get_attribute(name) 获取属性值
location 获取元素坐标,先找到要获取的元素,再调用该方法
page_source 返回页面源码
driver.title 返回页面标题
current_url 获取当前页面的URL
is_displayed() 设置该元素是否可见
is_enabled() 判断元素是否被使用
is_selected() 判断元素是否被选中
tag_name 返回元素的tagName
//元素操作
clear 清除元素的内容
send_keys 模拟按键输入
click 点击元素
submit 提交表单
//鼠标操作
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) ——发送某个键到指定元素
//键盘操作
send_keys(Keys.ENTER) 按下回车键
send_keys(Keys.TAB) 按下Tab制表键
send_keys(Keys.SPACE) 按下空格键space
send_keys(Kyes.ESCAPE) 按下回退键Esc
send_keys(Keys.BACK_SPACE) 按下删除键BackSpace
send_keys(Keys.SHIFT) 按下shift键
send_keys(Keys.CONTROL) 按下Ctrl键
send_keys(Keys.ARROW_DOWN) 按下鼠标光标向下按键
send_keys(Keys.CONTROL,'a') 组合键全选Ctrl+A
send_keys(Keys.CONTROL,'c') 组合键复制Ctrl+C
send_keys(Keys.CONTROL,'x') 组合键剪切Ctrl+X
send_keys(Keys.CONTROL,'v') 组合键粘贴Ctrl+V
=================================================================================
**此处是分割线,上面要讲的代码已经结束,下面记录一点其他的东西
Selenium三种等待方式
强制等待
可以看到,上面的代码中我最常用到的就是引入import time 调用 time.sleep() 这个是强制等待,就是执行到time.sleep(3)就必须强制等待上三秒才能执行接下来的代码。这种方式太死板,严重影响程序执行速度。
import time
#启动谷歌浏览器
driver = webdriver.Chrome()
#打开百度网址
driver.get("https://www.baidu.com/")
#强制等待三秒
time.sleep(3)
#执行下一步 在搜索框输入文字
driver.find_element(, 'kw').send_keys('Python3+Selenium3自动化测试')
隐性等待
听名字就知道,这是一个在后台默默工作的好员工了。driver.implicitly_wait(10),这是设置了一个最长的等待时间为10秒,意思是只要网页完整的加载完成了(划重点,是完整的加载完了,也就是说网站加载的那个圈圈啥时候停了才算是完整的加载完了),我就马上执行下一步,反之我则一直等待10秒后超时。driver.implicitly_wait()是在整个周期都起作用的,所有无需像leep一样,每次都调用一下哦。
隐性等待的弊端就是,等待整个界面加载完成太过于费时,可能我想要的某个元素早就加载完了,却还偏偏要等着别的元素一起加载完才能执行下一步。
#隐性等待10秒
driver.implicitly_wait(10)
driver.find_element(, 'kw').send_keys('Python3+Selenium3自动化测试')
driver.find_element(, 'su').click()
显性等待
WebDriverWait 这个比较灵活,他有until()和until_not()方法,他会每隔一段时间就判断条件是否成立,成立则执行下一步反之在超时之后抛出异常
until : 在等待期间会每隔一段时间就判断条件是否成立,成立后执行下一步反之超时后抛出异常
until_not :until的相反词,他是条件不成立或者某个元素消失后才会执行下一步
调用方法如下:
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
until()里面一定要是可执行的方法哦,如果是元素则会抛出异常
需要注意的地方:
此处虽然用的是显式等待,但是元素没有加载完成的时候还是会报错NoSuchElementException的(这个问题困扰了我大半天,太难了),所以记得加上一句隐式等待driver.implicitly_wait(10)
关于 presence 与 visibility
presence只需存在即可,不一定非要显示出来
visibility是可见的,需加载到页面中并显示出来
#额外需引入的包 (这个地方很有意思,竟然可以像数据库一样取别名,嫌弃名字太长的就取个别名吧 as xxx 即可)
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
#窗口最大化(试过,如果窗口小了要定位的元素没有显示完整是会报错的)
driver.maximize_window()
#显性等待
driver.get('https://www.baidu.com/')
#判断标题是否匹配,返回boolean
title = EC.title_is('百度一下,你就知道')
print(title(driver))
WebDriverWait(driver, 10).until(EC.title_is('百度一下,你就知道'))
WebDriverWait(driver, 10).until(EC.title_contains('百度一下,你就知道'))
'''
presence 与 visibility
presence只需存在即可,不一定非要显示出来
visibility是可见的,需加载到页面中并显示出来
'''
#一定要加,否则加载弹出的div时会报错NoSuchElementException
driver.implicitly_wait(10)
#常用的元素,也可以这样提前定义一下,但有些地方又用不了,不太懂
locator = (, 'kw')
wait = WebDriverWait(driver, 10)
#判断元素是否加载完成(只要加载到dom树即可,无论是否隐藏或显示)
wait.until(EC.presence_of_element_located(locator))
#判断元素是否加载到dom树并且可见 例如宽高大于0
wait.until(EC.visibility_of_element_located((, 'su')))
#判断元素是否可以,如可见则返回该元素
wait.until(EC.visibility_of(driver.find_element(, 'kw')))
#判断是否至少有一个元素在页面中可见,如果定位到就返回列表
#ps:这里(By.CSS_SELECTOR, '.mnav')必须用括号单独再括起来,看似多余,实则括起来则是一个完整的参数,反之则会被读取成两个参
wait.until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR, '.mnav')))
#判断是否至少有一个元素存在于dom树中,如果定位到就返回列表
wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.mnav')))
#判断指定的元素中是否包含预期字符串,返回boolean
wait.until(EC.text_to_be_present_in_element((By.XPATH, '//*[@id="s-usersetting-top"]'), '设置'))
#判断指定的元素属性值是否包含了预期字符串,返回boolean
wait.until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR, '#su'), '百度一下'))
#判断某个原木色是否存在dom树中或者不可见,可见则返回false,不可见返回元素
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, '#swfEveryCookieWrap')))
#判断某个元素是否可见并且是enable的,代表可点击
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="s-usersetting-top"]'))).click()
driver.find_element_by_xpath('//*[@id="s-usersetting-top"]').click()
driver.find_element_by_xpath('//*[@id="s-user-setting-menu"]/div/a[1]').click()
#判断某个元素是否被选中,通常用于下拉框、单(复)选框
wait.until(EC.element_to_be_selected(driver.find_element(By.XPATH, '//*[@id="s1_1"]')))
#判断某个元素的选中状态是否符合预期,两种写法
wait.until(EC.element_located_selection_state_to_be((By.XPATH, '//*[@id="s1_1"]'), True))
wait.until(EC.element_selection_state_to_be(driver.find_element(By.XPATH, '//*[@id="s1_1"]'), True))
driver.find_element(By.XPATH, '//*[@id="se-setting-7"]/a[1]').click()
#判断页面上是否存在alert,如果有就切换到alert并返回alert的内容
instance = wait.until(EC.alert_is_present())
print(instance.text)
'''下面两个案例无法从百度网页中完成测试,只做记录'''
#判断frame是否可以switch进去,如可以则返回true并switch进去,反之返回false
#wait.until(EC.frame_to_be_available_and_switch_to_it(locator))
#等待某个元素从dom树中移除
#wait.until(EC.staleness_of(driver.find_element(, 'su')))
想要知道EC调用后返回的结果可以这样写:
例如:
result = EC.element_selection_state_to_be(driver.find_element(By.XPATH, '//*[@id="s1_1"]'), True)
print(result(driver))
总结
以上就是今日所研究的内容,小白一枚,正在学习的路上,有什么不对之处欢迎指导