1.Selenium
Selenium
谷歌驱动下载: https://googlechromelabs.github.io/chrome-for-testing/
浏览器的基本操作(如打开浏览器、输入地址、网页最大化等):
from selenium import webdriver
# 打开浏览器
wd = webdriver.Chrome()
# 让浏览器打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')
# 网页最大化
wd.maximize_window()
选择元素的基本方法:
概念:
- 使用selenium中的find_element或find_elements方法来选择元素,返回值为WebElement对象,方法有两个参数:
- 参数一:指定哪种方式选择元素;
- 如:By.ID,By.CLASS_NAME,By.XPATH等;
- 参数二:根据不同的方式,使用不同的表达式来选择元素,如 css表达式等;
- 例子:
from selenium import webdriver
from selenium.webdriver.common.by import By
# 创建 WebDriver 对象
wd = webdriver.Chrome()
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID, 'kw')
# 通过该 WebElement对象,就可以对页面元素进行操作了
# 比如输入字符串到 这个 输入框里
element.send_keys('通讯\n')
find_element和find_elements:
find_element:用于选择的元素只有一个;
find_elements:用于选择的元素有多个;可以用下标去获取对应顺序的数据,如第一个数据 变量名[0]
选择元素方式:
- 根据id属性选择元素;
- 根据class属性选择元素;
- 根据css选择器选择元素(包含id和class);
- 根据Xpath选择器选择元素;
操控元素的基本方法:
点击元素:
概念:
调用元素WebElement对象的 click方法;
当我们调用 WebElement 对象的 click 方法去点击 元素的时候, 浏览器接收到自动化命令,点击的是该元素的 中心点 位置;
例子:
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID, 'kw')
# 点击该元素对应的webElement对象
element.click()
输入框:
概念:
为输入框写入数据,调用元素WebElement对象的send_keys方法;
输入框中已经有的内容清除掉,可以使用WebElement对象的clear方法;
例子:
element = wd.find_element(By.ID, "input1")
element.clear() # 清除输入框已有的字符串
element.send_keys('白月黑羽') # 输入新字符串
获取元素信息:
- 通过WebElement对象来获取元素信息;
参数 | 作用 |
---|---|
get_attribute('textContent')/get_attribute('innerText') | 获取元素标签的内容(文本信息) |
get_attribute('innerHTML') | 获取元素内的全部HTML |
get_attribute('outerHTML') | 获取包含选中元素的HTML |
get_attribute('value') | 获取输入框里面的字符串 |
get_attribute('属性') | 获取元素中的属性 |
CSS表达式:
根据 tag名、id、class 选择元素:
使用:
根据tag(标签)名 选择元素的语法无需添加任何前缀: div
根据id属性 选择元素的语法是在id号前面加上一个井号: #id值
根据class属性 选择元素的语法是在 class 值 前面加上一个点: .class值
例子:
# 通过标签名选择元素
wd.find_element(By.CSS_SELECTOR, "div")
# 通过id属性选择元素
wd.find_element(By.CSS_SELECTOR, "#id")
# 通过class属性选择元素
wd.find_element(By.CSS_SELECTOR, ".class")
选择 子元素 和 后代元素:
使用:
子元素是指父元素的直接后代元素;
后代元素是指包含在父元素内部的所有元素;
直接子元素的选择使用大于号;
后代元素的选择使用空格;
例子:
# 通过子元素选择元素
wd.find_element(By.CSS_SELECTOR, ".plant>span")
# 通过后代选择元素
wd.find_element(By.CSS_SELECTOR, ".plant span")
根据属性选择:
使用:
css选择器支持通过任何属性来选择元素,语法是用一个方括号 [属性名="属性值"];
id、class都是web元素的属性;
特殊用法:
选择元素 | 代码 |
---|---|
选择a节点,里面的href属性包含了 baidu 字符串 | a[href*="baidu"] |
要选择a节点,里面的href属性以 https 开头 | a[href^="https"] |
要选择a节点,里面的href属性以.com 结尾 | a[href$=".com"] |
选择含多个属性的元素,如<div class="plant" dtype="vegetables">白菜</div> | div[class="plant"][dtype="vegetables"] |
选择含有多个类的元素<div class="plant flower">西兰花</div> | div[class="plant flower"] |
例子:
# 通过属性选择元素; 例: 属性名: href,属性值: https://www.baidu.com
wd.find_element(By.CSS_SELECTOR, '[href="https://www.baidu.com"]')
组选择:
使用:
同时选择所有class 为 plant 和 class 为 animal 的元素; css选择器可以使用逗号 ,称之为 组选择 ;
例子:
# 通过组选择元素;
wd.find_element(By.CSS_SELECTOR, '.plant,.animal')
按次序选择子节点
父元素的第n个子节点:
使用:
指定选择的元素 是父元素的第几个子节点,使用 nth-child;
span:nth-child(2),表示第2个子元素,并且是span类型;
例子:
# 通过父元素的子节点选择元素; 子元素的第二个元素是span类型;
wd.find_element(By.CSS_SELECTOR, 'div>span:nth-child(2)')
父元素的倒数第n个子节点:
使用:
选择的是父元素的 倒数第几个子节点 ,使用 nth-last-child;
例子:
# 通过父元素的倒数子节点选择元素; 子元素的倒数第一个元素是p类型;
wd.find_element(By.CSS_SELECTOR, 'div>p:nth-last-child(1)')
父元素的第几个某类型的子节点:
使用:
指定选择的元素是父元素的第几个某类型的子节点;
例子:
# 通过父元素的子节点选择元素; 子元素是span类型下的第一个元素;
wd.find_element(By.CSS_SELECTOR, 'div>span:nth-of-type(1)')
父元素的倒数第几个某类型的子节点:
使用:
指定选择父元素的倒数第几个某类型的子节点;
例子:
# 通过父元素的倒数子节点选择元素; 子元素是span类型下的倒数第二个元素;
wd.find_element(By.CSS_SELECTOR, 'div>p:nth-last-of-type(2)')
奇数节点和偶数节点:
使用:
选择的是父元素的 偶数节点,使用 nth-child(even);
选择的是父元素的 奇数节点,使用 nth-child(odd);
如果要选择的是父元素的 某类型偶数节点,使用 nth-of-type(even);
如果要选择的是父元素的 某类型奇数节点,使用 nth-of-type(odd);
例子:
# 通过父元素的偶数子节点选择元素;
wd.find_elements(By.CLASS_NAME, 'div>p:nth-child(even)')
# 通过父元素的奇数子节点选择元素;
wd.find_elements(By.CLASS_NAME, 'div>p:nth-child(odd)')
# 通过父元素的某类型偶数节点选择元素;
wd.find_elements(By.CLASS_NAME, 'div>p:nth-of-type(even)')
# 通过父元素的某类型偶数节点选择元素;
wd.find_elements(By.CLASS_NAME, 'div>p:nth-of-type(odd)')
兄弟节点选择:
相邻兄弟节点选择:
使用:
选择元素后面紧跟着的兄弟节点;
选择 h3 后面紧跟着的兄弟节点 span, 可以这样写 h3 + span
例子:
# 通过元素的相邻兄弟节点选择元素;
wd.find_element(By.CSS_SELECTOR, 'h3 + span')
后续所有兄弟节点选择:
使用:
选择元素后面所有的兄弟节点;
选择是选择h3后面所有的兄弟节点span,可以这样写h3 ~ span;
例子:
# 通过元素的兄弟节点选择元素;
wd.find_elements(By.CSS_SELECTOR, 'h3 ~ span')
Xpath选择器:
简介:
绝对路径:
从根节点开始的,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的绝对路径;
如: /html/body/div
相对路径:
xpath需要前面加 // , 表示从当前节点往下寻找所有的后代元素,无需一级一级往下写;
如: //div//p 表示所有div下面的所有p元素;
//div/p 表示所有div下面的直接p子节点;
通配符:
* 是一个通配符,对应任意节点名的元素;
根据属性选择:
概念:
-
Xpath 可以根据属性来选择元素;
-
根据属性来选择元素 是通过 这种格式来的 [@属性名='属性值'];
根据id属性选择:
选择id为west 的元素,可以这样 //*[@id='west']
根据class属性选择:
选择所有select元素中class为single_choice 的元素,可以这样//select[@class='single_choice']
如果有多个class属性,需要把所有属性都写出来才可以;用空格分隔;
对应的xpath就应该是 //p[@class="capital huge-city"]
属性值包含字符串:
要选择 style属性值 包含 color 字符串的 页面元素 ,使用contains方法,可以这样 //*[contains(@style,'color')]
要选择 包裹指定字符的元素,使用contains和text方法,可以这样 //*[contains(text(), "被包裹的字符")]
要选择 style属性值 以 color 字符串 开头 的 页面元素 ,使用starts-with方法,可以这样 //*[starts-with(@style,'color')]
按次序选择:
概念:
xpath可以根据次序选择元素,直接在方括号中使用数字表示次序;
某类型 第几个 子元素:
要选择 p类型第2个的子元素,就是 //p[2]
第几个子元素:
使用通配符来指定第几个子元素;
选择父元素为div的第2个子元素,不管是什么类型 //div/*[2]
某类型 倒数第几个 子元素:
使用last()方法来指定倒数的元素;
选取p类型倒数第1个子元素 //p[last()]
选取p类型倒数第2个子元素 //p[last()-1]
选择父元素为div中p类型倒数第3个子元素 //div/p[last()-2]
范围选择:
xpath可以选择子元素的次序范围;
选取option类型第1到2个子元素 //option[position()<=2] 或者 //option[position()<3]
选择class属性为multi_choice的前3个子元素 //*[@class='multi_choice']/*[position()<=3]
选择class属性为multi_choice的后3个子元素 //*[@class='multi_choice']/*[position()>=last()-2]
组选择、父节点、兄弟节点:
组选择:
xpath有组选择, 是用 竖线 隔开多个表达式;
要选所有的option元素 和所有的 h4 元素,可以使用 //option | //h4
要选所有的 class 为 single_choice 和 class 为 multi_choice 的元素,可以使用
//*[@class='single_choice'] | //*[@class='multi_choice']
选择父节点:
xpath可以选择父节点, 这是css做不到的;
要选择 id 为 china 的节点的父节点,可以这样写 //*[@id='china']/..
兄弟节点选择:
xpath可以选择后续兄弟节点,用这样的语法 following-sibling::
要选择 class 为 single_choice 的元素的所有后续兄弟节点 //*[@class='single_choice']/following-sibling::*
等同于CSS选择器 .single_choice ~ *
前面最靠近的兄弟节点 , 这样写 //*[@class='single_choice']/preceding-sibling::*[1]
前面第2靠近的兄弟节点 , 这样写 //*[@class='single_choice']/preceding-sibling::*[2]
注意点:
要在某个元素内部使用xpath选择元素,需要在xpath表达式最前面加个点 ;
# 先寻找id是china的元素
china = wd.find_element(By.ID, 'china')
# 再选择该元素内部的p元素,需要在xpath表达式最前面加个点
elements = china.find_elements(By.XPATH, './/p')
# 打印结果
for element in elements:
print('----------------')
print(element.get_attribute('outerHTML'))
frame切换/窗口切换:
frame简介:
- iframe 元素非常的特殊, 在html语法中,frame 元素 或者iframe元素的内部 会包含一个 被嵌入的 另一份html文档。
- 在我们使用selenium打开一个网页是, 我们的操作范围 缺省是当前的 html , 并不包含被嵌入的html文档里面的内容。
- 如果我们要 操作 被嵌入的 html 文档 中的元素, 就必须切换操作范围 到 被嵌入的文档中。
frame切换:
-
使用 WebDriver 对象的 switch_to 属性中的frame()方法;
wd.switch_to.frame(frame_reference)
-
参数frame_reference 可以是 frame 元素的属性 name 或者 ID,如果都没有,可以使用WebElement 对象;
# id为frame1 wd.switch_to.frame('frame1') # name为innerFrame wd.switch_to.frame('innerFrame') # 使用webElement对象 wd.switch_to.frame(wd.find_element(By.TAG_NAME, "iframe"))
-
切换会原来的html页面,可以使用switch_to属性中的default_content()方法;
wd.switch_to.default_content()
窗口简介:
- 用Selenium写自动化程序 在新窗口里面 打开一个新网址我们的 WebDriver对象对应的 还是老窗口,自动化操作也还是在老窗口进行;
- 需要切换窗口来操作新打开的网址;
窗口切换:
-
使用Webdriver对象的switch_to属性的 window方法;
wd.switch_to.window(handle)
-
handle参数,可以使用Webdriver对象的window_handles属性来获取当前浏览器的所有页面的window_handles属性;
-
window_handles 属性,这是一个列表对象, 里面包括了当前浏览器里面所有的窗口句柄;
-
Webdriver对象的title属性用来获取当前网页的标题;
-
例子:
for handle in wd.window_handles: # 先切换到该窗口 wd.switch_to.window(handle) # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口 if 'Bing' in wd.title: # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环, break
-
获取当前网页的window_handle属性:
# mainWindow变量保存当前窗口的句柄 mainWindow = wd.current_window_handle #通过前面保存的老窗口的句柄,自己切换到老窗口 wd.switch_to.window(mainWindow)
选择框:
radio框:
使用:
radio框选择选项,直接用WebElement的click方法,模拟用户点击就可以了;
例子:
# 点选 小雷老师
wd.find_element(By.CSS_SELECTOR,'#s_radio input[value="小雷老师"]').click()
checkbox框:
使用:
对checkbox进行选择,也是直接用 WebElement 的 click 方法,模拟用户点击选择;
需要注意的是,要选中checkbox的一个选项,必须 先获取当前该复选框的状态 ,如果该选项已经勾选了,就不能再点击。否则反而会取消选择;
例子:
# 先把 已经选中的选项全部点击一下
elements = wd.find_elements(By.CSS_SELECTOR,'#s_checkbox input[name="teacher"]:checked')
for element in elements:
element.click()
# 再点击 小雷老师
wd.find_element(By.CSS_SELECTOR,"#s_checkbox input[value='小雷老师']").click()
select框:
使用:
对于Select 选择框, Selenium 专门提供了一个 Select类 进行操作;
Select类方法:
方法 | 简介 |
---|---|
select_by_value("value属性值") | 根据选项的 value属性值 ,选择元素; |
select_by_index("次序") | 根据选项的次序(从0开始),选择元素; |
select_by_visible_text("可见文本") | 根据选项的可见文本 ,选择元素; |
deselect_by_value("value属性值") | 根据选项的value属性值,去除 选中元素; |
deselect_by_index("次序") | 根据选项的次序,去除选中元素; |
deselect_by_visible_text("可见文本") | 根据选项的可见文本,去除选中元素; |
deselect_all() | 去除选中所有元素; |
例子:
# 导入Select类
from selenium.webdriver.support.ui import Select
# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_single"))
# 通过 Select 对象选中小雷老师
select.select_by_visible_text("小雷老师")
# 导入Select类
from selenium.webdriver.support.ui import Select
# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_multi"))
# 清除所有 已经选中 的选项
select.deselect_all()
# 选择小雷老师 和 小凯老师
select.select_by_visible_text("小雷老师")
select.select_by_visible_text("小凯老师")
更多动作:
ActionChains类:
概念:
ActionChains 类 里面提供了 一些特殊的动作的模拟;
比如 鼠标右键点击、双击、移动鼠标到某个元素、鼠标拖拽等;
方法:
- perform()方法写在所有链式方法最后,必写;
context_click("需要被使用的元素"):右击
double_click("需要被使用的元素"):双击
drag_and_drop("需要被拖动的元素", "拖拽的目标元素"):拖动
click_and_hold("需要被使用的元素"):按下鼠标左键在一个元素上(长按)
move_to_element("需要被使用的元素"):鼠标移动到某个元素
perform():执行链中的所有动作
pause():停留,参数为暂停时间
click():点击,参数为定位的元素,如若不指定,就为当前鼠标选中的元素
release():释放,参数为定位的元素,如若不指定,就为当前鼠标选中的元素
key_up():松开参数里的键,可以和Keys类搭配,表示松开快捷键
key_down():按下参数里的键,可以和Keys类搭配,表示按下快捷键
例子:
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://www.baidu.com/')
# 获取ActionChains对象
ac = ActionChains(driver)
e1 = driver.find_element(By.CLASS_NAME, "el-input__inner")
# 移动到某个元素上
ac.move_to_element(e1).perform()
鼠标滚动:
概念:
使用execute_script执行js语句实现页面滑动;
方法:
driver.execute_script("window.scrollTo(0,-document.body.scrollHeight)" )
删除css属性:
- 通过WebDriver对象来修改css属性样式;
- 方法:execute_script(参数一,参数二)
- 参数一:这是你要执行的JavaScript代码,如删除:
- arguments[0].removeProperty('property_name');
- 获取第一个参数(在这里是
element
)的样式对象,然后从该样式对象中移除名为property_name
的属性。
- 参数二:这是你要操作的DOM元素。你可以使用Selenium WebDriver的各种方法来定位这个元素
- 例子:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
# 定位到要修改的元素
element = driver.find_element_by_css_selector("your_css_selector")
# 使用JavaScript删除CSS属性
driver.execute_script("arguments[0].removeAttribute('target')", element)
键盘操作(Keys类):
概念:
Keys类给我们提供了大部分的键盘操作方法,如: 全选,复制,粘贴等都能模拟出来;
先用WebElement调用send_keys()方法,方法参数为Keys类中的方法;
也可以结合鼠标操作使用;
方法:
例子:
# 单独使用,按下全选,然后复制,然后粘贴,最后回车
driver.find_element(By.CLASS_NAME, "el-input__inner").send_keys(Keys.CONTROL,'a')
driver.find_element(By.CLASS_NAME, "el-input__inner").send_keys(Keys.CONTROL,'c')
driver.find_element(By.CLASS_NAME, "el-input__inner").send_keys(Keys.CONTROL,'v')
driver.find_element(By.CLASS_NAME, "el-input__inner").send_keys(Keys.ENTER)
# 结合鼠标操作使用,按下键盘上的control键,键盘操作-发送a键,然后鼠标操作-松开键盘上的control键
ActionChains(driver).key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform()
特殊操作:
冻结界面:
使用:
将页面冻结,使页面无法点击;
setTimeout(function(){debugger}, 5000): 固定用法,5000为5000毫秒,可以换成别的时间;
该方法是在5000毫秒后冻结页面;
例子:
setTimeout(function(){debugger}, 5000)
弹出对话框:
概念:
弹出的对话框有三种类型,分别是 Alert(警告信息)、confirm(确认信息)和prompt(提示输入);
它们都是使用 WebDriver 对象的 switch_to 属性中的alert下的方法和属性的;
wd.switch_to.alert
Alert(警告信息):
使用:
点击alert对话框: 使用 WebDriver 对象的 switch_to 属性中的alert下的accept()方法;
获取alert对话框里的内容: 使用 WebDriver 对象的 switch_to 属性中的alert下的text属性;
例子:
# 点击alert对话框:
wd.switch_to.alert.accept()
# 获取alert对话框里的内容:
wd.switch_to.alert.text
Confirm(确认信息):
使用:
点击confirm对话框的确认: 使用 WebDriver 对象的 switch_to 属性中的alert下的accept()方法;
点击confirm对话框的取消: 使用 WebDriver 对象的 switch_to 属性中的alert下的dismiss()方法;
获取confirm对话框里的内容: 使用 WebDriver 对象的 switch_to 属性中的alert下的text属性;
例子:
# 点击confirm对话框的确认:
wd.switch_to.alert.accept()
# 点击confirm对话框的取消:
wd.switch_to.alert.dismiss()
# 获取confirm对话框里的内容:
wd.switch_to.alert.text
prompt(提示输入框):
使用:
输入内容到prompt对话框中: 使用 WebDriver 对象的 switch_to 属性中的alert下的send_keys()方法;
点击prompt对话框的确认: 使用 WebDriver 对象的 switch_to 属性中的alert下的accept()方法;
点击prompt对话框的取消: 使用 WebDriver 对象的 switch_to 属性中的alert下的dismiss()方法;
获取prompt对话框里的内容: 使用 WebDriver 对象的 switch_to 属性中的alert下的text属性;
例子:
# 输入内容到prompt对话框中:
wd.switch_to.alert.send_keys('输入内容')
# 点击prompt对话框的确认:
wd.switch_to.alert.accept()
# 点击prompt对话框的取消:
wd.switch_to.alert.dismiss()
# 获取prompt对话框里的内容:
wd.switch_to.alert.text
文件上传:
AutoIt第三方插件:
使用autoIt通过脚本来录制上传文件的;
然后转换为exe文件;
WinActivate("打开的窗口名")
ControlFocus("打开的窗口名","","文件框的唯一标识符")
// 等待10秒
WinWait("[CLASS:#32770]","",10)
ControlSetText("打开的窗口名","","文件框的唯一标识符","上传的文件位置")
// 等待2000毫秒
sleep(2000)
ControlCick("打开的窗口名","","按钮的唯一标识符")
- 在selenium中用os.system("生成的exe文件")
import os
os.system("文件路径")
window平台专用上传:
-
使用pip install pypiwin32安装专有库;
-
使用:
#先点击打开上传文件 from time import sleep # 等到上传选择文件对话框打开 sleep(2) # 前提是浏览器必须是当前应用 import win32com.client shell = win32com.client.Dispatch("WScript.Shell") # 输入文件路径, 最后的'\n',表示回车确定, 也可以是'\r' 或者 '\r\n' shell.Sendkeys(r"c:\666.jpg"+'\r\n') sleep(1)
浏览器的三种等待方式
强制等待sleep:
-
设定大概的等待睡眠时间,无论是否找到元素都必须强制等待设置的睡眠时间结束
-
from time import sleep sleep(10)
显示等待:WebDriverWait
-
相对智能的等待方式,可以通过设置等待条件是否达成来决定是否终止等待。若在等待时间内发现等待元素,可提前终止等待;若是等待时间结束还未找到页面元素,就抛出异常。
-
可以使用lambda表达式来使用,如:
-
from selenium.webdriver.support.ui import WebDriverWait # 显示等待,超时时长10秒,周期0.2秒刷新一次 WebDriverWait(driver, 10, 0.2).until(lambda el:定位的元素)
隐式等待:
-
使用implicitly_wait()方法设置等待时间,在等待时间内发现元素可提早结束等待,若等待时间结束后仍找不到元素,就抛出异常
-
wd.implicitly_wait(10)
浏览器设置:
设置浏览器窗口的大小:
- 使用
set_window_size
方法,来设置浏览器的大小
driver.set_window_size(width,height)
最大化浏览器;
- 使用
maximize_window
方法,来最大化浏览器
driver.maximize_window()
移动浏览器窗口到指定位置:
- 使用
set_window_position
方法,来移动浏览器窗口到指定位置;
driver.set_window_position(x,y) # 移动浏览器窗口到指定位置
网页截图:
- 使get_screenshot_as_file('图片名称')方法,来实现网页截图;
driver.get_screenshot_as_file('1.png') #截图放在当前文件夹下,命名为1.png
driver.get_screenshot_as_file(r'd:\1.png') #截图存放在d盘下,命名为1.png
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现