• 元素操作(二)


    一. 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():获取弹出框的内容

    总结:

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

    二. 切换alert   switch_to.alert

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

    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. 存储鼠标操作(用列表的形式按先后顺序来存储)

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

    支持的操作如下:

    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()--鼠标悬停。以后会经常遇到

    实例:

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

    代码如下:

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

    三. 下拉列表操作

    观察下拉框页面元素,是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()

    Select类—下拉框操作

    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(文本内容)

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

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

    四. 窗口切换

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

    如何切换到新窗口?

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

    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的

    代码运行后,上传成功:

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

  • 相关阅读:
    php程序去除文件 bom头
    类继承接口后,实现接口的方法
    virtual和abstract的使用场景分别是什么?待更新。
    get请求和post请求的总结
    ES6新语法,持续更新
    display:flex中的不懂的问题,待处理
    css相邻兄弟选择器(+),伪类(:hover),伪元素(::after)
    HTML中的input的type类型
    命令行打开程序的集合
    sqlserver 常用的语句
  • 原文地址:https://www.cnblogs.com/my_captain/p/9235781.html
Copyright © 2020-2023  润新知