元素操作

Posted cnhkzyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了元素操作相关的知识,希望对你有一定的参考价值。

一. windows弹出框的处理

1. 真实案例

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

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

技术分享图片

 

2. 解决办法

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

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

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

  • accept():是

  • dismiss():否

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

3. 实例

假设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脚本的运行结果也打印了弹出框的文本内容

技术分享图片

二. 鼠标操作

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

 

引入ActionChains类

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

 

主要操作流程:

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

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

 

支持的操作如下:

double_click   双击操作

context_click   右键操作

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

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

 

实例:

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

技术分享图片

代码如下:

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.实例化ActionChains(driver)  2.要干什么事move_to_element(setting_element)  3.执行这个事perform()
ActionChains(driver).move_to_element(setting_element).perform()

三. 下拉列表操作

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

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

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

 

思路:

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

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

 

两种方式:

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

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

 

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

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

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

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()

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

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()

四. 窗口切换

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

如何切换到新窗口?

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

 

1. 获取当前所有的窗口

windows = diver.window_handles

2. 切换到指定的窗口

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

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

3. 切回原来的窗口

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

4. 获取当前窗口的句柄

chrome.current_window_handle

 

实例

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)

五. 上传操作

 

有两种情况:

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库,识别对话框句柄,进而操作

 

工具:

pywin32和spy++

 

下载安装:

pywin32

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

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

 

WinSpy

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

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

 

例:百度网盘—上传窗口,利用winSpy可以看到从顶层到文件路径输入区域总共有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) #点击打开按钮

 

详细说明:

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参数

 

WinSpy图解:

一级窗口

技术分享图片

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

技术分享图片

 二级窗口ComboBoxEx32

技术分享图片

 二级窗口打开(&0)

 技术分享图片

三级窗口ComboBox

 技术分享图片

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

技术分享图片

 

代码运行后,上传成功:

技术分享图片

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

技术分享图片

 

以上是关于元素操作的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构

VSCode自定义代码片段5——HTML元素结构

CSS代码片段

CSS代码片段

css有用的代码片段