元素操作(二)

1|0一. windows弹出框的处理


1|11. 真实案例


有时候,我们会在页面中遇到windows弹出框,和页面弹出框不同,windows弹出框不能用F12查看html源码来定位元素,对于这种弹出框应该作何处理呢?

例如:博客园中点击退出按钮,会弹出一个确认是否退出的弹出框,此时按F12是没有作用的

 

1|22. 解决办法


1) 确认浏览器弹出框存在

2) 使用switch_to方法切换到windows弹出框,driver.switch_to.alert

3) Alert类提供了一系列的操作方法。利用Alert的方法,选择接受(accept)或者拒绝(dismiss)

  • accept():是

  • dismiss():否

  • text():获取弹出框的内容

 

总结:

一. 用显性等待,等待alert弹出框出现   alert_is_present()

二. 切换alert   switch_to.alert

三. 操作它,选择接受或者拒绝,还可以获取弹出框文本内容

 

1|33. 实例


假设python脚本的同级目录下存在一个test_alert.html的文件,代码和效果如下:

#在python脚本的同级目录下有一个test_alert.html文件 <html> <head> <meta charset="utf-8"> <title>html表单作业-2</title> <script type="text/javascript"> function myFunc(){ var username = document.getElementById("username").value; alert("用户名为:" + username); } </script> </head> <body> <form> 用户名:<input type="text" id="username" name="username" /> <br /> 密码:<input type="password" id="passwd" name="passwd" /> <br /> <input type="button" value="登录" onclick="myFunc()" />&nbsp;&nbsp; <input type="reset" value="重置" /> </form> </body> </html>

点击登录按钮,会弹出一个windows弹出框

现在虽然无法通过F12定位这个弹出框,但可以通过switch_to.alert切换到这个弹出框,再利用Alert类提供的方法,来点击确定按钮

from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import os #确认浏览器弹出框存在 #切换到弹出框 #选择yes或者no, 关闭弹出框 driver = webdriver.Chrome() driver.get(os.getcwd() + "/test_alert.html") driver.maximize_window() #点击登录,让windows弹出框出现 driver.find_element_by_xpath("//input[@value='登录']").click() #等待弹出框出现 WebDriverWait(driver, 10, 0.5).until(EC.alert_is_present()) #切换到弹出框 alert = driver.switch_to.alert #打印弹出框文本内容 print(alert.text) #点击确定,接受弹出框 alert.accept()

python脚本的运行结果也打印了弹出框的文本内容

2|0二. 鼠标操作


由selenium的ActionChains来完成模拟鼠标操作

 

2|1引入ActionChains类


from selenium.webdriver.common.action_chains import ActionChains AC.方法名1().context_click().perform()

 

2|2主要操作流程:


1. 实例化鼠标类

2. 存储鼠标操作(用列表的形式按先后顺序来存储)

3. perform()来执行鼠标操作

 

2|3支持的操作如下:


double_click   双击操作

context_click   右键操作

drag_and_drop   拖拽操作。左键按住拖动某一个元素到另外一个区域,然后释放按键

#定位元素的原位置 element = driver.find_element_by_name("source") #定位元素要移动到的目标位置 target = driver.find_element_by_name("target") #执行元素的移动操作 ActionChains(driver).drag_and_drop(element, target).perform()

 

move_to_element()--鼠标悬停。以后会经常遇到

 

2|4实例:


比如想让鼠标悬停在百度首页的菜单栏的设置上

代码如下:

from selenium.webdriver.common.action_chains import ActionChains from selenium import webdriver driver = webdriver.Chrome() driver.get("http://www.baidu.com") #定位设置 setting_xpath = "//*[@id='u1']//a[@class='pf']" setting_element = driver.find_element_by_xpath(setting_xpath) #鼠标悬浮 #1.实例化鼠标类 2.调用各种鼠标行为 3.调用perfrom()方法去执行鼠标操作 ActionChains(driver).move_to_element(setting_element).perform()

3|0三. 下拉列表操作


观察下拉框页面元素,是select/option还是ul/li

1. 菜单栏—点击其中的某个链接跳转

2. 在下拉列表中选择一个值

 

3|1思路:


1. 等待下拉列表和下拉列表中值存在

2. 对下拉列表中的元素进行操作

 

3|2两种方式:


一. 获取所有的下拉列表值,然后用循环取匹配相同的值

二. 通过text的内容来找到下拉列表的某个值

 

比如现在要去百度首页的设置里,点开设置是个下拉列表,在这个列表中选择高级搜索并点击

注意:高级搜索定位时,需要先点击设置,在高级搜索出现后,再按ctrl + shift + C快捷键来获取高级搜索的定位

3|3方法一:根据文本内容来获取对应的元素


from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains #初始化chromedriver driver = webdriver.Chrome() #隐性等待30s driver.implicitly_wait(30) #打开百度首页 driver.get("http://www.baidu.com") #窗口最大化 driver.maximize_window() #设置的元素表达式 setting_xpath = "//div[@id='u1']//a[@name='tj_settingicon']" #定位到设置 setting_element = driver.find_element_by_xpath(setting_xpath) #鼠标悬浮 ActionChains(driver).move_to_element(setting_element).perform() #选择下拉列表当中高级搜索选项 #1.等待下拉列表,你要选择的元素在页面可见 #2.再去下拉列表当中选择它 advance_search_xpath = "//div[@class='bdpfmenu']//a[text()='高级搜索']" driver.find_element_by_xpath(advance_search_xpath).click()

3|4方法二:获取整个下拉列表中的所有元素,然后再去选择一个


from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains #初始化chromedriver driver = webdriver.Chrome() #隐性等待30s driver.implicitly_wait(30) #打开百度首页 driver.get("http://www.baidu.com") #窗口最大化 driver.maximize_window() #设置的元素表达式 setting_xpath = "//div[@id='u1']//a[@name='tj_settingicon']" #定位到设置 setting_element = driver.find_element_by_xpath(setting_xpath) #鼠标悬浮 ActionChains(driver).move_to_element(setting_element).perform() #获得设置里所有的列表元素对象 all_element = driver.find_elements_by_xpath("//div[@class='bdnuarrow']//following-sibling::a") #对于元素对象列表,如果其元素对象的文本内容是高级搜索,则点击它 for i in all_element: if i.text == "高级搜索": i.click()

3|5Select类—下拉框操作


selenium提供了Select类来处理select/option

 

引入类:

from selenium.webdriver.support.ui import Select

 

选择下拉列表值:

1. 通过下标选择:select_by_index(index)   从0开始

2. 通过value属性:select_by_value(value值)

3. 通过文本内容:select_by_visible_text(文本内容)

 

3|6实例:打开百度首页——设置——高级搜索,并在文档格式里选择其中三项


from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import Select import time #初始化chromedriver driver = webdriver.Chrome() #打开百度首页 driver.get("http://www.baidu.com") #窗口最大化 driver.maximize_window() #百度首页设置的元素表达式 setting_xpath = "//div[@id='u1']//a[@name='tj_settingicon']" #设置显性等待,等待设置可见 WebDriverWait(driver, 3, 0.3).until(EC.visibility_of_element_located((By.XPATH, setting_xpath))) #定位到设置 setting_element = driver.find_element_by_xpath(setting_xpath) #鼠标悬浮 ActionChains(driver).move_to_element(setting_element).perform() #高级搜索的元素表达式 advance_serach_xpath = "//a[text()='高级搜索']" #设置显性等待,等待高级搜索可见 WebDriverWait(driver, 3, 0.3).until(EC.visibility_of_element_located((By.XPATH, advance_serach_xpath))) #定位到高级搜索并点击 driver.find_element_by_xpath(advance_serach_xpath).click() #select下拉框的元素表达式 select_name = "ft" #设置显性等待,等待select下拉框可见 WebDriverWait(driver, 3, 0.3).until(EC.visibility_of_element_located((By.NAME, select_name))) #定位到select下拉框 select_element = driver.find_element_by_name(select_name) #通过下标选择:选择下标为2的选项——微软 Word (.doc) Select(select_element).select_by_index(2) #等待2s time.sleep(2) #通过value属性选择:选择value值为“rtf”的选项——RTF 文件 (.rtf) Select(select_element).select_by_value("rtf") #等待2s time.sleep(2) #通过文本内容选择:选择文本内容为所有格式的选项 Select(select_element).select_by_visible_text("所有格式") #等待3s time.sleep(3) #断开连接 driver.quit()

 

4|0四. 窗口切换


在页面中点击某个链接之后,就会打开一个新的窗口

如何切换到新窗口?

若新窗口操作之后,需要切换回原来的窗口?

 

4|11. 获取当前所有的窗口


windows = diver.window_handles

4|22. 切换到指定的窗口


注意:switch_to.window()和switch_to_window()都可以,但后者将淘汰,建议用前者

chrome.switch_to.window(windows[-1]) #最新打开的窗口

4|33. 切回原来的窗口


chrome.switch_to.window(windows[0]) #切换到第一个窗口

4|44. 获取当前窗口的句柄


chrome.current_window_handle

 

4|5实例


from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By #初始化chromedriver driver = webdriver.Chrome() #隐性等待30s driver.implicitly_wait(30) #打开百度首页 driver.get("http://www.baidu.com") #窗口最大化 driver.maximize_window() #定位到输入框,并输入内容selenium driver.find_element_by_id("kw").send_keys("selenium") #定位到百度一下按钮并点击 driver.find_element_by_id("su").click() #获取当前浏览器打开的所有窗口 handlers = driver.window_handles #打印当前浏览器打开的窗口数 print(len(handlers)) #定位selenium官网链接 selenium_officer_xpath = "//a[contains(text(), 'Web Browser Automation')]" driver.find_element_by_xpath(selenium_officer_xpath).click() #等待新的窗口出现 WebDriverWait(driver, 30, 1).until(EC.new_window_is_opened(handlers)) #获取到当前浏览器打开的所有窗口 handlers = driver.window_handles #打印当前浏览器打开的窗口数 print(len(handlers)) #切换到新的窗口,进行新页面的操作 driver.switch_to.window(handlers[-1]) #定位到Projects并点击 driver.find_element_by_xpath("//li[@id='menu_projects']//a").click() #切换回原来的窗口 driver.switch_to.window(handlers[0]) #获取当前窗口的句柄并打印 current_handler = driver.current_window_handle print(current_handler)

5|0五. 上传操作


 

5|1有两种情况:


1. 如果是input,可以直接输入路径的,那么直接调send_keys输入路径

2. 非input标签的上传,则需要借助第三方工具

  2.1 AutoIt  我们去调用其生成的au3或exe文件(需要了解)

  2.2 SendKeys第三方库(目前只支持到2.7版本)  网址:https://pypi.org/project/SendKeys

  2.3 Python pywin32库,识别对话框句柄,进而操作

 

5|2工具:


pywin32和spy++

 

5|3下载安装:


pywin32

下载地址:https://sourceforge.net/projects/pywin32

安装方法:https://jingyan.baidu.com/article/bad08e1ed173d409c85121f8.html

 

WinSpy

下载地址:https://sourceforge.net/projects/winspyex

安装方法:下载为压缩包,解压后即可

 

例:百度网盘—上传窗口,利用winSpy可以看到从顶层到文件路径输入区域总共有4层

 

 

 

5|4上传操作代码:


#以chrome浏览器为例

import
win32gui import win32con dialog = win32gui.FindWindow("#32770", "打开") #一级窗口 #找到窗口 ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None) #二级
button = win32gui.FindWindowEx(dialog, 0, "Button", None) #二
comboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, "ComboBox", None) #三级 edit = win32gui.FindWindowEx(comboBox, 0, "Edit", None) #四级 #操作 win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, "D:\\apk.txt") #发送文件路径 win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button) #点击打开按钮

 

5|5详细说明:


win32gui.FindWindow(IpClassName, IpWindowName)

自顶层窗口开始寻找匹配条件的窗口,并返回这个窗口的句柄

IpClassName:类名,在Spy++里能够看到

IpWindowName:窗口名,标题栏上能看到的名字

 

win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, IpszClass=None, IpszWindow=None)

搜索类名和窗体名匹配的窗体,并返回这个窗体的句柄。找不到就返回0

hwndParent:若不为0,则搜索句柄为hwndParent窗体的子窗体

hwndChildAfter:若不为0,则按照z-index的顺序从hwndChildAfter向后开始搜索子窗体,否则从第一个子窗体开始搜索

IpClassName:字符型,是窗体的类名,这个可以在Spy++里找到

IpWindowName:字符型,是窗口名,也就是标题栏你能看到的那个标题

 

win32gui.SendMessage(hWnd, Msg, wParam, IParam)

hWnd:整型,接收消息的窗体句柄

Msg:整型,要发送的消息,这些消息都是windows预先定义好的

wParam:整型,消息的wParam参数

IParam:整型,消息的Param参数

 

5|6WinSpy图解:


一级窗口

 一级窗口下的子窗口,可以看到有打开按钮,还有ComboBoxEx32

 二级窗口ComboBoxEx32

 二级窗口打开(&0)

 

三级窗口ComboBox

 

 四级窗口Edit,它是没有Text的

 

5|7代码运行后,上传成功:


注意:需要上传的文件不能为空文件,否则会上传失败

 


__EOF__

本文作者cnhkzyy
本文链接https://www.cnblogs.com/my_captain/p/9235781.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cnhkzyy  阅读(423)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示