- 1 打开 / 关闭浏览器
- 2 打开URL链接
- 3 定位单个页面元素
- 3.1 通过ID定位
- 3.2 通过name定位
- 3.3 通过classname定位
- 3.4 通过CSS定位
- 3.5 通过链接的文本信息定位
- 3.6 通过XPath定位
- 3.6.1 xpath语法
- 3.6.2 实例
- 4 操作
- 4.1 基本操作
- 4.2 切换窗口、框架
- 5 封装selenium的基本操作
- 6 判断元素是否存在
1、通过页面开发者工具(点击键盘F12或者空白处右击点击检查)中的element,查看页面html代码;
2、点击开发者工具左上角鼠标按钮;
3、鼠标移动至需要定位元素位置;
4、高亮显示;
5、右击选择定位方式。
1 打开 / 关闭浏览器
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
url = 'https://www.csdn.net/'
browser.get(url)
browser.maximize_window()
time.sleep(5)
# browser.close()
browser.quit()
注意:
关闭浏览器close和quit的区别:
以下是两个函数的描述,可见close() 只关闭当前窗口;quit() 退出驱动程序并关闭所有相关窗口。
def close(self) -> None:
"""
Closes the current window.
:Usage:
::
driver.close()
"""
self.execute(Command.CLOSE)
def quit(self) -> None:
"""
Quits the driver and closes every associated window.
:Usage:
::
driver.quit()
"""
try:
self.execute(Command.QUIT)
finally:
self.stop_client()
self.command_executor.close()
2 打开URL链接
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
time.sleep(5)
browser.quit()
3 定位单个页面元素
使用find_element函数来定位元素。
3.1 通过ID定位
id值在一个页面中是唯一的。
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
time.sleep(5)
browser.find_element(By.ID, "toolbar-search-input").send_keys("python")
time.sleep(5)
browser.find_element(By.ID, "toolbar-search-button").click()
time.sleep(5)
browser.quit()
3.2 通过name定位
name属性在同一个表单中唯一,但在页面不唯一。若有两个name属性相同的元素,使用该方法会定位到name属性第一次出现的地方。
browser.find_element(By.NAME, "username").click()
3.3 通过classname定位
class属性同样不唯一,页面中可能会出现多个,使用该方法定位到的也是第一个拥有该class属性的元素。
browser.find_element(By.CLASS_NAME, "blog-nav-box").click()
3.4 通过CSS定位
传入的参数格式:标签名[属性名=属性值],通过标签与属性的组合来唯一的定位页面元素
browser.find_element(By.CSS_SELECTOR, "input[id='toolbar-search-input']").click()
3.5 通过链接的文本信息定位
这种方法只适合定位链接元素
browser.find_element(By.By.LINK_TEXT, "Python").click()
3.6 通过XPath定位
browser = webdriver.Chrome()
browser.get('https://www.csdn.net/')
browser.maximize_window()
browser.find_element(By.XPATH, '//*[@id="csdn-toolbar"]/div/div/div[3]/div/div[3]/a').click()
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys("人工智能")
browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]').click()
time.sleep(5)
browser.quit()
3.6.1 xpath语法
/ | 表示一个层级,从根节点开始定位(绝对路径) |
---|---|
// | 表示多个层级,从任意位置开始定位 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
* | 匹配任何元素节点 |
//* | 选取文档中的所有元素 |
---|---|
@* | 匹配任何属性节点 |
//title[@*] | 选取所有带有属性的title元素 |
3.6.2 实例
/div/div[3] | 选取div下的第三个div的元素 |
---|---|
//div | 选取所有div元素,不管他们在文档中的位置 |
div//title | 选取div元素的后代的所有title元素 |
//@lang | 选取名为lang的所有属性 |
//title[@lang='eng] | 选取所有title元素,并且带有值为eng的lang属性 |
//div|//title | 选取文档中的所有div和title元素 |
4 操作
4.1 基本操作
# 清除文本框内容:使用clear()方法
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').clear()
# 点击
browser.find_element(By.XPATH, '//*[@id="toolbar-search-button"]').click()
# 填写文本内容
browser.find_element(By.XPATH, '//*[@id="toolbar-search-input"]').send_keys("人工智能")
# 获取元素的属性信息:使用get_attribute(“属性名”)
browser.find_element(by, element_value).get_attribute('value')
4.2 切换窗口、框架
# 切换fram框架, "frame_value"可以是id、name属性值,也可以是序号index,假如有2个iframe
# 第一个序号就是0
browser.switch_to.frame(frame_value)
# 切换窗口
handles = browser.window_handles # 获取当前全部窗口句柄集合
now_handle = driver.current_window_handle # 获取当前窗口句柄
browser.switch_to.window(now_handle) # 切换至当前窗口
# 切换alert
# accept - 点击【确认】按钮
# dismiss - 点击【取消】按钮(如有按钮)
# send_keys - 输入内容(如有输入框)
alert = switch_to.alert().accept() #点击确认
5 封装selenium的基本操作
def open_browser0(public_devices):
"""
打开浏览器------无头模式
:param public_devices:
"""
global browser
ch_options = Options()
ch_options.add_argument("--headless") # 为chrome设置无头模式 options=ch_options
public_devices.driver = webdriver.Chrome()
log.info("打开浏览器:%s" % public_devices.driver)
browser = public_devices.driver
browser.get("http://%s" % public_devices.path)
log.info("get_url: %s" % public_devices.path)
browser.maximize_window()
time.sleep(2)
def close_browser():
"""
logout,并关闭浏览器
"""
global browser
browser.quit()
log.info("关闭浏览器")
@exist
def logout(element_value, element_type):
"""
退出登录
"""
global browser
alert_prencence()
res = browser.switch_to.default_content()
log.info("切换至默认frame")
click_element_by(element_value, element_type)
log.info("退出登录")
def execute(cmd):
"""
执行命令
:param cmd:
"""
global browser
log.info(browser.execute(cmd))
def refresh():
"""
刷新页面
"""
global browser
browser.refresh()
log.info("刷新页面")
time.sleep(2)
@exist
def check_element(node_element):
"""
判断用户是否可见该节点元素
:param node_element:
:return:
"""
if node_element.is_displayed():
return True
else:
return False
def switch_to_frame(frame_value):
"""
切换fame
:param frame_value:
"""
global browser
browser.switch_to.frame(frame_value)
log.info("切换frame到:%s" % frame_value)
def switch_to_window(window_value, window_type):
"""
切换浏览器窗口
:param window_value:
:param window_type:
"""
global browser
handles = browser.window_handles
log.info(browser.switch_to.window(handles[window_value]))
@exist
def set_element_text(element_value, set_value, element_type):
"""
输入框输入
:param element_value:元素定位
:param set_value:要设置的值
:param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
"""
global browser
by = whichType(element_type)
browser.find_element(by, element_value).send_keys(set_value)
log.info("输入:%s", set_value)
time.sleep(2)
@exist
def clear_element_text(element_value, element_type='XPATH'):
"""
清空输入框
:param element_value:元素定位
:param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
"""
global browser
by = whichType(element_type)
log.info(browser.find_element(by, element_value).clear())
time.sleep(2)
@exist
def get_text(element_value, element_type):
"""
获取元素,并打印
:param element_value:元素定位
:param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
"""
global browser
by = whichType(element_type)
element = browser.find_elements(by, element_value)
res = element.__getattribute__('text')
log.info("获取元素", res)
return res
@exist
def get_element_attribute(element_value, element_type):
"""
获取元素属性并返回
:param element_value:元素定位
:param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
:return:
"""
global browser
by = whichType(element_type)
attribute = browser.find_element(by, element_value).get_attribute('value')
log.info("获取元素属性:%s", attribute)
return attribute
@exist
def click_element_by(element_value, element_type):
"""
点击元素
:param element_value:元素定位
:param element_type:元素类型,支持id、xpath、link_text、partial_link_text、name、tag_name、class_name、css_selector
"""
global browser
by = whichType(element_type)
log.info("点击元素 %s", element_value)
browser.find_element(by, element_value).click()
time.sleep(2)
def alert_prencence():
result = EC.alert_is_present()(browser)
if result:
log.info(result.text)
result.accept()
else:
log.info("未弹出!")
6 判断元素是否存在
通过添加装饰器,不改变原函数代码、不改变函数返回值,判断元素是否存在。
def exist(func):
"""
装饰器,判断元素是否存在
:param func:需要判断元素的函数
:return:函数
"""
global browser
def wrapper(*args, **kwargs):
keys = inspect.signature(func).parameters # 得到的是不可迭代对象
keys_str = str(keys)
if keys_str.find('element_type') >= 0 and keys_str.find('element_value') >= 0:
# 变成list后,可根据索引获取参数名对应的参数值
keys_lis = list(keys)
index_type = keys_lis.index("element_type") # 获取元素类型索引
index_value = keys_lis.index("element_value") # 获取元素值索引
element_type = whichType(args[index_type]) # 取对应索引参数值
element_value = args[index_value]
try:
WebDriverWait(browser, 5, 0.5).until(EC.presence_of_element_located((element_type, element_value)))
return func(*args, **kwargs)
except TimeoutException as e:
log.error("timeout")
raise ElementnotFoundException(element_type, element_value)
return wrapper
class ElementnotFoundException(Exception):
"""
自定义异常
:param
:return:字符串
"""
def __init__(self, element_type, element_value):
self.element_type = element_type
self.element_value = element_value
def __str__(self):
log.error("\n找不到元素: %s" % self.element_value)
# return "\n找不到元素: %s" % self.element_value