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选择器支持通过任何属性来选择元素,语法是用一个方括号 [属性名="属性值"];
idclass都是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]
选择父元素为divp类型倒数第3个子元素 //div/p[last()-2]
范围选择:
xpath可以选择子元素的次序范围;
选取option类型第12个子元素 //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类中的方法;
也可以结合鼠标操作使用;
方法:

img

例子:
# 单独使用,按下全选,然后复制,然后粘贴,最后回车
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): 固定用法,50005000毫秒,可以换成别的时间;
该方法是在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
posted @   回家太晚太悲催  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示