• UI自动化


     
    selenium:
    ide -录制
    webdriver -库 提供了网页的操作方法
    grid -分布式,多浏览器并发执行用例

    pip3 install -U selenium
    安装:ie-ieserverdriver
    chrome-chromedriver
    firefox-geckodriver

    浏览器驱动:http://npm.taobao.org/mirrors/chromedriver/
    驱动版本与浏览器需要匹配,最好关闭浏览器更新功能

    通信流程:
    1.xxxdriver(浏览器驱动)启动,ip+端口监听
    2.python selenium webdriver跟浏览器驱动建立链接,发送http请求
    3.浏览器驱动收到指令,驱动浏览器做操作
    4.浏览器驱动把结果返回给 python selenium webdriver
    5.继续发下一个http请求
    6.最后断开链接,关闭驱动,关闭浏览器



    定位方式:
    1.根据元素属性来查找元素:
    id :有可能不是唯一,或每次请求都会变,需注意
    name
    class_name 只能选class值中的一个
    tag_name
    display:None 属性会隐藏

    2.只针对a元素:
    link_text
    partial_link_text 部分文本链接

    3.多个属性组合查找元素:
    xpath
    css_selector

    4.a = document.getElementById("q")
    a.readOnly = true#输入框改为无法输入
    a.disabled = true#输入框改为无法输入

    <iframe src="http://www.baidu.com" frameborder="0" width="550"></iframe> #内嵌窗口

    <textarea name="" id="" cols="30" rows="10"></textarea> #多行文本域

    <!-- 表格-->
    <table>
    <th></th>表头
    <tr></tr>列
    <td></td>行
    </table>

    <!-- 列表-->
    <ul>
    <li></li>
    </ul>

    <!-- 块级元素-->
    <div>
    <!-- 链接-->
    <a href="http://www.taobao.com">
    <span>点我去买买买!</span> #类似这种行级元素 优先定位a元素
    </a>
    </div>

    <!-- 图片-->
    <br>#换行
    <img src="http://www.baidu.com/img/bd_logo1.png" alt="" style="400px;height:100px;">


    from selenium import webdriver
    import time

    # 启动Chrome浏览器
    driver = webdriver.Chrome()

    # 打开百度首页
    driver.get("http://www.baidu.com")

    # 最大化窗口
    driver.maximize_window()

    # 设置成浏览器窗口大小,宽400,高600
    driver.set_window_size(400, 600)

    #沉睡5秒
    time.sleep(5)

    driver.get("http://www.taobao.com")

    # 退回到百度首页
    driver.back()

    # 前进到淘宝页面
    driver.forward()

    #刷新
    driver.refresh()

    #关闭当前窗口
    driver.close()

    #退出webdriver程序
    driver.quit()

    元素四大操作:click(),send_keys(),get_attribute(),text

    # elements匹配多个元素返回列表

    #id
    driver.find_element_by_id('kw').send_keys('selenium')

    #class
    #只能匹配class属性中的一个值
    driver.find_element_by_class_name('s_ipt').send_keys('selenium12')

    #name
    driver.find_element_by_name('wd').send_keys('selenium14')

    #tag
    # HTML是通过tag来定义功能的,比如input是输入,table是表格等.每个元素其实就是一个tag,很难通过tag去区分不同的元素仅了解就行。下面代码仅做参考,运行时必定报错
    # driver.find_element_by_tag_name('input').send_keys('selenium16')


    #link_text
    # 此种方法是专门用来定位文本链接的
    driver.find_element_by_link_text('新闻').click()

    #partial_link_text
    # 一个超链接的文本很长很长如果全部输入,既麻烦,又显得代码很不美观,这时候我们就可以只截取一部分字符串,用这种方法模糊匹配了。
    driver.find_element_by_partial_link_text('消').click()


    #Xpath
    driver.find_element_by_xpath("//*[@id='kw']").send_keys('selenium')

    绝对定位:
    以/开头,父/子顺序, full xpath
    /html/body/div[3]/div[4]/div/div[1]/div/h2/a, div[3]:html下面的body下面的第三个div......
    //*[@id="guonei"]/div[1]/div/h2/a, 绝对相对定位组合

    相对定位:(定位不要有下标不要单斜杠,越灵活越好):工作中的定位一般就以下6种可满足
    以//开头
    1.标签名[@属性=值],如果不是唯一就继续往父亲爷爷找
    //a[@href="/guonei"]
    //*[@*="/guonei"]:通配只要结果等于guonei

    2.层级定位(使用最多)://一级元素//二级元素......
    //div[@class="civilnews"]//a[@href="/guonei"]
    //div[@id="number-attend"]//i[@class="ing"]
    
    
    


    3.文本定位://标签名[text()=值]
    //a[text()="公告"]

    4.包含定位,可以包含属性和文本:如课堂派每个课程的id都不一样,要取到该课程的公告,就需要用到如下包含属性的方法定位
    //标签名[contains(@属性/text(),值)]
    属性://a[contains(@href,"/Notify/index/courseid/")]
    文本://a[contains(text(),"公告")]

    5.逻辑运算定位 来组合更多元素特征,适用于更复杂定位,and or
    //标签名[@属性=值 or @属性=值]
    //标签名[@属性=值 and @属性=值 and contains(@属性/text(),值) and text()=值]

    //a[text()="公告" and contains(@href,"/Notify/index/courseid/")]


    6.轴定位:关系定位,一般应用场景是表格样式的数据列,需要用组合来定位元素
    a.通过兄弟姐妹找到自己
    b.通过后代元素找到祖先元素

    轴运算:
    ancestor:所有的祖先包括父亲
    parent:父亲节点
    preceding:当前元素节点之前的所有节点(html页面的先后顺序)
    preceding-sibling:当前元素节点之前的所有兄弟节点
    following:当前元素节点之前的所有节点(html页面的先后顺序)
    following-sibling:当前元素节点之后的所有兄弟节点
    语法:
    已知元素/轴名称::标签名称[@属性=值]
    例如,根据写忆找到阿花 ://p[@title="写忆"]/parent::*/following-sibling::li//p[@class="name"]
    先找写忆》再找写忆的父亲》再找他父亲的弟弟》根据他父亲的弟弟找到需要的元素,默认是第一个,如果不是第一个继续用下标再找
    //p[@title="路飞"]/preceding-sibling::p[@class="stuno"]
    //p[@title="路飞"]/following-sibling::p[@class="stuno"]

       7.如果在打开的页面定位到了元素,实际运行代码时报错无法找到元素, 这时需要打断点观察,或者在代码运行时打开的页面用ctrl+f将写好的定位去查找试试
        
        driver.save_screenshot()#如果代码运行错误调试时可以再前面加上截图,默认保存在当前目录下
    
    

     


        7.下标、js


    #css
    # 这种方法相对xpath要简洁些,定位速度也要快些,但是学习起来会比较难理解,
    driver.find_element_by_css_selector('#kw').send_keys('selenium')
    定位例子:
      

     

     

     

     

     

     如下弹窗可以使用sources进行暂停定,然后进行定位操作

     

     

    
    
    




    等待操作以:显性为主,sleep为辅
    1.sleep >强制等待
    2.智能等待:最多愿意等10秒,如果在10秒内出现就继续下一行代码,超时异常:TimeoutException,NosuchElementException
    隐形等待:2种场景,a.每个会话中只调用一次,适用全局,会话就是打开浏览器到quit关闭的整个过程,
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    driver.get('http://www.baidu.com')
    b.元素存在可见,元素被找到
               c.等待元素可见,url跳转,新的窗口出现,等待元素可见,隐形等待是处理不了的,需要显性等待处理

    显性等待:在你需要的地方直接用显性等待,那个地方需要用在哪个地方,一般工作中使用显性为主sleep为辅,有些元素明明是对的就是定位不到可加sleep调试
    等待:等待上限 - 15秒,轮询周期 - 多少秒去确认一下条件是否成立,默认是0.5
    条件:专门的条件模块,Expected_condition :期望的条件
    等待 + 条件:WebDriverWait(driver,15,0.5).until/not_until(条件)

    from selenium.webdriver.support.wait import WebDriverWait,类
    from selenium.webdriver.support import expected_conditions as EC,模块

    loc = ("xpth",'//p[@title="路飞"]/following-sibling::p[@class="stuno"]')
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc))
    located一般在自动化中为:元素定位, visibility_of_element_located():等待到当前元素可见后,才获取元素。

    等待:
    1.页面跑不过代码
    2.设备原因,性能
    3.页面渲染


    三大切换之windows窗口切换:

    窗口切换,简单来说就是在原来的页面窗口下打开了一个新的窗口,需要要新的窗口中,去进行下一步的操作。

    因此 需要知道:

    1)怎么知道需要切换到哪个窗口?

    2)代码程序怎么知道哪个窗口是新的窗口?

    步骤:

    1)得到目前打开的所有窗口。

    这里要引入句柄的概念,每个窗口都有一个句柄。 句柄是一个数字标识

    所有窗口显示集合是一个列表。其顺序是:先出现的,先追加到列表;新的窗口,在列表的最后。

    即最先打开的窗口,在列表第一个;

    # 获取所有的窗口句柄
    wins = driver.window_handles
    print(wins)

    2)切换到新窗口

    # 切换到新的窗口
    driver.switch_to.window(wins[-1])
    print("切换之后的句柄:",driver.current_window_handle)

    3)在新的窗口里,定位元素操作元素

    示例:

    这里以在百度中输入“”搜索selenium webdriver“”,并在搜索结果中找到官网(切换到官网窗口),执行下载文件操作。

    import time
    from  selenium import  webdriver
    from selenium.webdriver.common.by import By
    from  selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    # 1、打开访问百度
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://www.baidu.com/")
    
    # 2、在百度首页输入框中输入selenium webdriver
    # 1)定位到百度首页输入框:根据ID定位
    # 2)在输入框中输入:selenium webdriver
    # 3)点击百度一下:根据ID定位,后加点击操作_click()
    element = driver.find_element_by_id("kw")
    element.send_keys("selenium webdriver")
    driver.find_element_by_id("su").click()
    
    # 3、在搜索到的页面结果中找到 - SeleniumHQ Browser Automation
    loc =(By.XPATH, '//a[text()=" - SeleniumHQ Browser Automation"]')
    # 使用显性等待10秒,构建使得loc元素是可见的
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc))
    # 触发新的窗口出现:找到 - SeleniumHQ Browser Automation元素后,点击跳转到先窗口
    driver.find_element_by_xpath('//a[text()=" - SeleniumHQ Browser Automation"]').click()
    # 强制等待1秒
    time.sleep(1)
    
    # 4、获取所有的窗口句柄
    wins = driver.window_handles
    print(wins)
    
    # 5、获取自己当前所在的窗口句柄
    print(driver.current_window_handle)
    
    # 6、切换到新的窗口
    driver.switch_to.window(wins[-1])
    print("切换之后的句柄:",driver.current_window_handle)
    
    # 7、在新的窗口等待查找的元素,并对元素进行点击操作
    loc2 = (By.XPATH,'//div[@class="download-button webdriver"]')
    WebDriverWait(driver,15).until(EC.visibility_of_element_located(loc2))
    driver.find_element(*loc2).click()  #loc2为一个元祖里面有2个数值,*loc2脱衣服变为2个数值
    
    # 8、退出会话
    time.sleep(5)
    driver.quit()

     三大切换之iframe和Alert切换

    一、web窗口之iframe窗口切换

    首先,iframe是html里面的html页面。

    若遇到要操作的元素,在iframed当中,则需要进行此操作。

    操作步骤:

    1)判断要操作的元素是否在iframe当前,可使用元素定位方法进行判断;

    2)若1中判断元素存在。则需要再判断切换到哪个iframe中。

    3)切换方法:

    driver.switch_to.frame()

    参数支持3种方式来确定切换到哪个一个iframe:

    #1) iframe下标 从0开始
    driver.switch_to.frame(3)
    
    #2) iframe元素的name属性
    driver.switch_to.frame("login_frame_qq")
    
    #3) iframe这个webElment元素。
    driver.switch_to.frame(driver.find_element_by_xpath('//iframe[@name="login_frame_qq"]))

    具体实现的流程:

    1)打开访问的页面;

    2)根据元素定位等操作,进入到有iframe的页面;

    3)操作到有iframe的页面当中,且后面的操作,是在此iframe中找到元素并操作;

    4)切换到iframe窗口,进入下一代html当中

    driver.switch_to.frame("iframe窗口_名称")

    5)在firame窗口中定位元素操作;

    6) 回到默认的html页面当中 - 第一代
    driver.switch_to.default_content()

    7)回到上一级的iframe - 上一代
    driver.switch_to.parent_frame()

    import time
    from  selenium import  webdriver
    from selenium.webdriver.common.by import By   
    from  selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    # 1、打开访问腾讯课堂
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://ke.qq.com/")
    
    # 2、根据xpath定位当前页面登录按钮,点击登录进入QQ登录窗口
    loc = (By.XPATH,'//a[@id="js_login"]')
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc))
    driver.find_element_by_xpath('//a[@id="js_login"]').click()
    
    # 3、强制等待1秒
    time.sleep(1)
    
    # 4、在新的弹窗中找到QQ登录按钮,点击进入QQ登录账号密码输入框
    loc2 = (By.XPATH,'//i[@class="icon-font i-qq"]')
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc2))
    driver.find_element_by_xpath('//i[@class="icon-font i-qq"]').click()
    
    # 5、在QQ账号登录窗口
    loc3 =(By.XPATH,'//iframe[@name="login_frame_qq"]')
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc3))
    driver.find_element_by_xpath('//iframe[@name="login_frame_qq"]').click()
    
    # 6、切换到新的iframe的窗口
    driver.switch_to.frame("login_frame_qq")
    
    # 7、在QQ登录窗口定位到QQ账号信息
    loc4 =(By.XPATH,'//*[@id="img_out_1xxxx"]')
    WebDriverWait(driver,20).until(EC.visibility_of_element_located(loc4))
    driver.find_element_by_xpath('//*[@id="img_out_1xxxx"]').click()
    
    # 9、退出会话
    time.sleep(10)
    driver.quit()

    二、web窗口之Alert(弹窗)切换

    很多时候我们会遇到弹窗,且必须对弹窗操作后才能对页面进行操作。弹窗的优先级比网页中的任意元素高;

    这里就以这种类型的窗口进行操作。

    步骤:

    1)点击触发操作,触发弹窗出现;

    driver.find_element_by_id("press").click()

    2)等待弹窗出现;

    3)将操作切换到弹窗;

    driver.switch_to.alert

    4)将弹窗关掉,进行下一步的页面处理操作

    print(alert.text)
    alert.accept
    
    #点击弹窗上确定按钮
    alert.accept();
    #点击弹窗的取消按钮
    alert.dismiss()
    #获取弹窗上线上的文本文字内容
    alert.getText();
    #有些弹窗还支持文本输入,这个可以把要输入字符通过sendkeys方法输入
    alert.sendkeys();

    例子:

    """
    alert类
    """
    import time
    
    from  selenium import  webdriver
    
    driver = webdriver.Chrome()
    driver.get("E:WorkspacepythonWebclass_05_0307MyHtml.html")
    
    # 点击动作,触发弹框出现
    driver.find_element_by_id("press").click()
    # 等待弹窗出现
    time.sleep(1)
    
    # 切换弹窗
    alert = driver.switch_to.alert
    
    # 将弹窗关掉,进行下一步的页面处理
    print(alert.text)
    alert.accept()
    
    # 关闭会话
    time.sleep(5)
    driver.quit()


    prompt() 方法用于显示可提示用户进行输入的对话框。
    confirm()方法用于显示一个带有指定消息和确认及取消按钮的对话框。

    三大操作(鼠标,下拉列表,按键操作)

    一、鼠标操作

    参数都是元素对象,除了与坐标有关的函数外;

    函数名:ActionChains 动作链

    常见的鼠标操作:

    1)悬浮 move_to_element
    2)点击 click
    3)双击 double_click
    4)右键 context_click
    5)拖拽 drag_and_drop
    6)暂停 pause
    7)输入 send_keys

    操作步骤:

    1)将要执行所有鼠标的动作,先放到一个列表当中。

    2)perform() : 执行鼠标动作。

    示例:

    示例:
    在百度首页中的设置中找到高级设置((鼠标悬浮在设置上后出现高级设置))
    
    import time
    
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://www.baidu.com/")
    
    # 1、找到鼠标要操作的元素(百度首页的设置)
    loc = (By.XPATH, '//div[@id="u1"]//a[@name="tj_settingicon"]')
    ele = driver.find_element(*loc)
    ele.click()
    
    # 2、实例化Actonchains类
    ac = ActionChains(driver)
    
    # 3、调用鼠标行为(悬浮)
    ac.move_to_element(ele)
    
    # 4、调用perform()来执行鼠标动作
    ac.perform()
    time.sleep(2)
    
    # # 注: 若将2、3、4操作结合到一起
    # ActionChains(driver).move_to_element(ele).perform()
    
    # 5、等待 下拉列表中元素可见
    loc2 = (By.XPATH, '//a[text()="高级搜索"]')
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located(loc2))
    
    # 6、选择想要操作的元素
    # 触发高级搜索内容出现
    driver.find_element(*loc2).click()

    二、下拉列表操作(Select类)

    使用Select类进行操作

    1)初始化,传select对象;

    2)根据下标、value属性、文本内容来选择值;

    示例:

    在上面案例的基础上操作(对百度高级设置中的文件格式下拉框进行选择操作)

    from selenium.webdriver.support.select import Select
    
    # 1、初始化,传select对象
    loc3 = (By.XPATH, '//select[@name="ft"]')
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located(loc3))
    select_element = driver.find_element(*loc3)
    
    s = Select(select_element)
    
    # 2、根据下标 value属性、文本内容来选择值
    # 根据下标选值
    s.select_by_index(6)
    time.sleep(3)
    # 根据value属性选值
    s.select_by_value("doc")
    time.sleep(3)
    # 根据文件内容选值
    s.select_by_visible_text('RTF 文件 (.rtf)')
    time.sleep(3)
    
    # 3、关闭会话
    time.sleep(5)
    driver.quit()

    三、键盘操作(Keys类)

    Keys类中处理特殊键

    示例:

    在百度首页找到搜索输入框,输入内容后,点击百度一下的鼠标操作使用enter键替代

    import time
    from  selenium import webdriver
    from  selenium.webdriver.common.keys import  Keys
    
    # 1、打开访问百度首页
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("http://www.baidu.com")
    # 2、找到搜索输入框,输入selenium webdriver,按enter键进行搜索
    element = driver.find_element_by_id("kw")
    element.send_keys("selenium webdriver", Keys.ENTER)
    # 3、关闭会话
    time.sleep(5)
    driver.quit()
    
    send_keys(Keys.F12)
    #键盘F12 send_keys(Keys.ESPACE)#回退键Esc send_keys(Keys.BACK_SPACE)#删除键BackSpace element.send_keys(Keys.CONTROL,"c")# ctrl+c 复制 driver.find_element_by_id("kw").send_keys(Keys.PageDown)#下拉页面(相当于滑动下拉框到底部)

     

    日期时间控件操作:

    如下形式:

    有readonly=‘true’ 属性的。(日期选择器的日期字段不允许输入)

    from selenium import webdriver
    import time
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(20)
    driver.get("http://xxxx/pages/systemManagement/login.html")
    driver.find_element_by_xpath("/html/body/div/input").send_keys('xx')
    driver.find_element_by_xpath('/html/body/div1/input').send_keys('xxx')
    driver.find_element_by_xpath('/html/body/div/div[7]').click()
    driver.find_element_by_xpath('/html/body/li[1]/a').click()
    # js = "document.getElementById('c-date1').removeAttribute('readonly')" # 1.原生js,移除属性
    # js = "$('input[id=c-date1]').removeAttr('readonly')" # 2.jQuery,移除属性
    # js = "$('input[id=c-date1]').attr('readonly',false)" # 3.jQuery,设置为false
    js = "$('input[id=c-date1]').attr('readonly','')" # 4.jQuery,设置为空(同3)
    driver.execute_script(js)
    
    driver.find_element_by_id('c-date1').send_keys('10/16/2017')
    time.sleep(15)
    driver.quit()

    另一种例子:

    from selenium import webdriver
     
    driver  = webdriver.Chrome()
     
    # pha_js = "var a = arguments[0];a.readOnly=false;a.value= arguments[1];"
     
    loc = ("xpath","//*[@id='train_date']")
    ele = driver.find_element(*loc)
     
    now_10 = "1111"  # datetime获取当前时间
     
    driver.execute_script("var a = arguments[0];a.readOnly=false;a.value= arguments[1];",ele,now_10) #ele传给了arguments[0];now_10传给了arguments[1]

    没有readonly=‘true’直接send_keys

    from selenium import webdriver
    import time
    
    driver = webdriver.Chrome()
    driver.get("http://jqueryui.com/resources/demos/datepicker/other-months.html")
    driver.find_element_by_id('datepicker').send_keys("10/16/2017")
    time.sleep(5)
    driver.quit()

     12306查票操作,请用javascript实现出发地和目的地的选择,日期处理,并提交查询操作

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    driver = webdriver.Chrome()
    driver.maximize_window()
    driver.get("https://www.12306.cn/index/")
    
    time.sleep(5)
    
    # 1)找到出发地的操作的元素
    loc_from = (By.XPATH, '//*[@id="fromStation"]')
    from_element = driver.find_element(*loc_from)
    from_station = "SHH"
    
    loc_from_T = (By.XPATH, '//*[@id="fromStationText"]')
    from_element_T = driver.find_element(*loc_from_T)
    from_station_T = "input inp-txt_select"
    from_station_Value = "上海"
    
    # driver.execute_script("var a = arguments[0];a.value= arguments[1]; ", from_element, from_station)
    driver.execute_script("var a = arguments[0];a.value= arguments[1]; var b = arguments[2];b.className= arguments[3];b.value =arguments[4];",
                          from_element,from_station,from_element_T,from_station_T,from_station_Value)
    
    # 2) 找到目的地的操作的元素
    loc_to = (By.XPATH, '//*[@id="toStation"]')
    to_element = driver.find_element(*loc_to)
    to_station = "GZG"
    driver.execute_script("var a = arguments[0];a.value= arguments[1];", to_element, to_station)
    
    loc_to_T = (By.XPATH, '//*[@id="toStationText"]')
    to_element_T = driver.find_element(*loc_to_T)
    to_station_T = "input inp-txt_select"
    to_station_Value = "赣州"
    driver.execute_script("var b = arguments[0];b.class= arguments[1];b.value = arguments[2];",  to_element_T, to_station_T,to_station_Value)
    
    # 3)找到查询时间的操作的元素
    loc_time = (By.XPATH, '//*[@id="train_date"]')
    time_element = driver.find_element(*loc_time)
    train_date = "2020-04-01"
    driver.execute_script("var a = arguments[0];a.readOnly=false;a.value= arguments[1];", time_element, train_date)
    
    # 4)输入完成,找到查询按钮,点击查询
    loc_find = (By.XPATH, '//*[@id="search_one"]')
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located(loc_find))
    driver.find_element(*loc_find).click()
    
    
    # 5)关闭连接
    time.sleep(10)
    driver.quit()

    滚动条操作:

    1、使用 JS 滑动纵向滚动条

    from selenium import webdriver
    from time import sleep
    
    # driver = webdriver.Chrome()
    driver = webdriver.Firefox()
    driver.get("http://www.baidu.com")
    driver.find_element_by_id('kw').send_keys("storm")
    driver.find_element_by_id('su').click()#滑动滚动条到底部
    js1 = "window.scrollTo(0, document.body.scrollHeight)"#滑动到顶部
    js2 = "window.scrollTo(0,0)"#向下移动200像素
    js3 = "window.scrollTo(0,200)"#滑动滚动条到某个指定的元素
    js4 = "arguments[0].scrollIntoView();"sleep(2) #等待页面加载完,注意观察滚动条目前处于最上方
    driver.execute_script(js1) #执行js1,将滚动条滑到最下方
    sleep(2) #加等待时间,看效果
    driver.execute_script(js2) #执行js2,将滚动条滑到最上方
    sleep(2) #加等待时间,看效果
    driver.execute_script(js3) #执行js3,将滚动条向下滑到200像素
    sleep(2) #加等待时间,看效果
    driver.execute_script(js2) #执行js2,将滚动条滑到最上方
    sleep(2)
    ele = driver.find_element_by_id('con-ar')  #定位一个元素
    driver.execute_script(js4,ele)  #滑动到上面定位的元素的地方
    sleep(2)
    driver.quit()
    
    
    #以上语句Chrome 和 Firefox 浏览器测试都没问题

    2、使用 JS 滑动横向滚动条:

    from selenium import webdriver
    from time import sleep
    
    driver = webdriver.Chrome()
    # driver = webdriver.Firefox()
    driver.get("http://www.baidu.com")
    driver.find_element_by_id('kw').send_keys("storm")
    driver.find_element_by_id('su').click()
    
    driver.set_window_size(500,500) #缩小浏览器窗口,使之出现横向滚动条
    
    js5 = "window.scrollTo(document.body.scrollWidth,0)"
    js6 = "window.scrollTo(0,0)"
    js7 = "window.scrollTo(200,0)"
    
    driver.execute_script(js5)  #移动到最右边
    sleep(2)
    driver.execute_script(js6) #移动到最左边
    sleep(2)
    driver.execute_script(js7) #向右移动200像素
    sleep(2)
    driver.quit()

    3、操作内嵌滚动条:

    内嵌滚动条,一般嵌在一个iframe 里面,先切到要操作滚动条所在的iframe里面

    from selenium import webdriver
    from time import sleep
    
    driver = webdriver.Chrome()
    # driver = webdriver.Firefox()
    driver.get("http://sahitest.com/demo/iframesTest.htm")
    sleep(2)
    driver.switch_to.frame(1)
    js5 = "window.scrollTo(0,200)"
    driver.execute_script(js5)  #向下移动200像素
    sleep(2)
    driver.quit()
    总结一下:
    
    1、使用window.scrollTo(x,y) 这一语句,可以实现所有的纵向或横向滑动滚动条。其中x为横坐标,y为纵坐标,想纵向滚动200像素,就window.scrollTo(0,200)
    
    2、 获取当前窗口的高度和宽度
    
    document.body.scrollWidth
    
    document.body.scrollHeight
    
    3、滑动到指定元素位置
    
    arguments[0].scrollIntoView() ,arguments[0] 是指第一个传参

    另一个例子:
    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 time
    
    driver = webdriver.Chrome()
    
    driver.get("http://www.baidu.com")
    
    element = driver.find_element_by_id("kw")   
    element.send_keys("selenium webdriver")
    driver.find_element_by_id('su').click()  
    
    
    # js当中,将元素拖动到可视区域的js语句。
    # 如何确认在当前网页当中,是否需要将元素拖动到可视区域?
    
    # loc = (By.XPATH,'//div[@id="page"]//span[text()="2"]')
    loc = (By.XPATH,'//a[text()=" 常用API - Ethon - 博客园"]')
    WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc))
    a = driver.find_element(*loc)
    
    # # js函数 - 元素对象.scrollIntoView();
    # driver.execute_script('arguments[0].scrollIntoView(false);',a)  # arguments 接收外部参数。列表。
    # # a.click()
    
    # 滚动到页面底部
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
    time.sleep(2)
    
    # 滚动到页面顶部
    driver.execute_script("window.scrollTo(document.body.scrollHeight,0)")

    京东网站实例:
    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
     
    driver = webdriver.Chrome()
    driver.get('http://www.baidu.com')
    driver.implicitly_wait(5)
    driver.maximize_window()
    ele = driver.find_element_by_id('kw')
    ele.send_keys("京东商城", Keys.ENTER)
    loc = (By.XPATH, '//a[contains(text(),"正品低价、品质保障")]')
    WebDriverWait(driver, 20).until(EC.visibility_of_element_located(loc))
    driver.find_element(*loc).click()
    win = driver.window_handles
    driver.switch_to.window(win[-1])
    # driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
    # 京东页面的内容 - 滚动多少,加载多少。所要操作的内容,并不知道大概要滚动多少。
    lo = (By.XPATH, '//*[@id="J_top"]/div[1]/a/h3')
    # 获取当前的窗口大小。整个窗口的高和宽。
    win_size = driver.get_window_size()
    # 窗口有window.outerHeight(包含工具栏和滚动条),window.innerHeight(不包含工具栏和滚动条,仅内容可视区域)
    # 获取当前窗口的内容可视区域
    inner_height = driver.execute_script("var a = window.innerHeight;return a;")
    print("当前窗口的内容可视区域-高度:",inner_height)
    # 获取当前整个html页面的body高度。
    body_height = driver.execute_script("var a = document.body.scrollHeight;return a;")
    print("当前整个html页面的body-高度:",body_height)
     
    scrolled_height = 0
    new_body_height = body_height
    old_body_height = 0
    break_flag = False
    while new_body_height != old_body_height:
        distance = int((new_body_height -scrolled_height)/ (inner_height * 0.5)) + 1
        for i in range(distance):
            # 滚动距离为 窗口内容可视区域的百分之50.可灵活配置哦!
            driver.execute_script("var a = window.innerHeight;window.scrollBy(0,a*0.5);")
            # 滚动一次,页面内容会更新一部分。在滚动之后,查找当前页面是否包含了它。如果没有,继续滚动。如果有,退出。
            try:
                WebDriverWait(driver, 10).until(EC.visibility_of_element_located(lo))
            except:
                pass
            else:
                print("找到啦!!!")
                driver.find_element(*lo).click()
                break_flag = True # 终止for循环
                break
        if break_flag is True:  # 终止While循环
            break
            # time.sleep(3)
        # 更新滚动
        old_body_height = new_body_height
        scrolled_height = new_body_height
        new_body_height = driver.execute_script("var a = document.body.scrollHeight;return a;")
        print("老 - 当前整个html页面的body-高度:", old_body_height)
        print("新 - 当前整个html页面的body-高度:", new_body_height)

     文件上传:

    上传按钮的种类,大体上分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input

    1. input标签是可以直接send_keys的

    from selenium import webdriver
    
    driver = webdriver.Firefox()
    driver.get('http://sahitest.com/demo/php/fileUpload.htm')
    upload = driver.find_element_by_id('file')
    upload.send_keys('d:\baidu.py')  # send_keys
    print upload.get_attribute('value')  # check value
    
    driver.quit()

    2.非input标签

    不是input框实现的上传有a标签的,有用div的,有用button的,有用object的,没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开OS弹框,去处理弹框。

    大体上有以下几种解决方案:

    1. autoIT,借助外力,我们去调用其生成的au3或exe文件。
    2. Python pywin32库,识别对话框句柄,进而操作
    3. SendKeys库,不推荐,不稳定
    4. keybd_event,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v…不推荐,不稳定

    a.win32gui

    from selenium import webdriver
    import win32gui
    import win32con
    import time
    
    dr = webdriver.Firefox()
    dr.get('http://sahitest.com/demo/php/fileUpload.htm')
    upload = dr.find_element_by_id('file')
    upload.click()
    time.sleep(1)
    
    # win32gui
    dialog = win32gui.FindWindow('#32770', u'文件上传')  # 对话框
    ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None) 
    ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
    Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)  # 上面三句依次寻找对象,直到找到输入框Edit对象的句柄
    button = win32gui.FindWindowEx(dialog, 0, 'Button', None)  # 确定按钮Button
    
    win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\baidu.py')  # 往输入框输入绝对地址
    win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)  # 按button
    
    print upload.get_attribute('value')
    dr.quit()

    需要下个小工具:Spy++,也可以用autoIT自带的工具,不过没有这个好用,你得安装pywin32的库,你可以到这里找到对应你Python版本的库,注意32位还是64位一定要和你安装的Python版本对应。

     c.多文件上传

    多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
    “D:a.txt” “D:.txt”


    但需要注意的是:只有多个文件在同一路径下,才能这样用,否则是会失败的(下面的写法是不可以的):
    “C:a.txt” “D:.txt”

    from selenium import webdriver
    import win32gui
    import win32con
    import time
    
    dr = webdriver.Firefox()
    dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/20150128-1')
    
    dr.switch_to.frame('iframe')  # 一定要注意frame
    dr.find_element_by_class_name('filePicker').click()
    time.sleep(1)
    
    dialog = win32gui.FindWindow('#32770', None)
    ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
    ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
    Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
    button = win32gui.FindWindowEx(dialog, 0, 'Button', None)
    
    # 跟上面示例的代码是一样的,只是这里传入的参数不同,如果愿意可以写一个上传函数把上传功能封装起来
    win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, '"d:\baidu.py" "d:\upload.py" "d:\1.html"')
    win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)
    
    
    print dr.find_element_by_id('status_info').text
    dr.quit()
    '''百度首页搜索上传图片为例'''

    #前提条件 1.使用winspy定位绝对路径
    #前提条件 2.安装库pywin32 采用pip安装pip install pywin32 或其他途径安装

    #1.访问百度网址
    #2.点击图片按钮

    #3.点击上传

    #4.使用winspy工具定位路径输入框 和打开按钮 如何定位请自行查找 参考https://www.cnblogs.com/xiaogongjin/p/11546518.html#4361591

    #5.输入绝对路径,点击打开 ,前提条件为,windows 上传弹框已经可见,可以sleep1-2秒等待出现
    from selenium import webdriver
    import win32gui
    import win32con
    import time
    driver=webdriver.Chrome()
    driver.get('https://www.baidu.com')
    driver.maximize_window()#最大
    driver.find_element_by_class_name('soutu-btn').click()
    time.sleep(2)
    imgpath='D:\abc.jpg'
    driver.find_element_by_class_name('upload-pic').click()
    time.sleep(2)
    # driver.find_element_by_class_name('upload-pic').send_keys('imgpath')
    #一级顶层窗口,此处title为上传窗口名称,浏览器不一样上传窗口名称不一样
    dialog = win32gui.FindWindow("#32770",'打开')
    #二级窗口
    ComboBoxEx32 = win32gui.FindWindowEx(dialog,0,"ComboBoxEx32",None)
    #三级窗口
    comboBox = win32gui.FindWindowEx(ComboBoxEx32,0,"ComboBox",None)
    #四级窗口
    edit = win32gui.FindWindowEx(comboBox,0,'Edit',None)
    button = win32gui.FindWindowEx(dialog,0,'Button',None)
    #执行操作 输入文件路径
    win32gui.SendMessage(edit,win32con.WM_SETTEXT,None,'D:\abc.jpg')
    #点击打开上传文件
    win32gui.SendMessage(dialog,win32con.WM_COMMAND,1,button)
    打包封装方法
    def file_upload(self,filePath,browser_type='chrome'):
    '''
    windows 上传弹框已经可见,可以sleep1-2秒等待出现
    :param filePath: 文件绝对路径例 D:\123.abc
    :param browser: 浏览器类型默认为 chrome
    :return:
    '''
    if browser_type.lower()== 'chrome':
    title='打开'
    elif browser_type.lower()== 'Firefox':
    title='文件上传'
    elif browser_type.lower() =='ie':
    title='选择要加载的文件'
    logging.info('本次使用{0}进行上传操作'.format(browser_type))
    # 一级顶层窗口,此处title为上传窗口名称,浏览器不一样上传窗口名称不一样
    dialog = win32gui.FindWindow("#32770", title)
    # 二级窗口
    ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None)
    # 三级窗口
    comboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, "ComboBox", None)
    # 四级窗口,编辑按钮 edit = win32gui.FindWindowEx(comboBox, 0, 'Edit', None)
    # 二级窗口,打开按钮 button
    = win32gui.FindWindowEx(dialog, 0, 'Button', None) # 执行操作 输入文件路径 win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, filePath) # 点击打开上传文件 win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)


    # 等上传窗口出现
    time.sleep(2)
    file_upload("E:WorkspacepythonWebxxxxx.py")

    winspy工具的定位方法采用的是绝对路径定位,即根路径为点击上传按钮后的弹出框的整个窗口页面,一般根据Text文本值和Class属性来定位,如图所示:

     根路径如图所示,它的Text文本值为“打开”,Class属性值为“#32770”。

     在winspy工具左上角有个聚焦按钮,通过拖动的方式拖动到上传弹出框的对应位置(如文件路径输入框)后松开,winspy界面会显示当前定位的Text文本值(此处为空)和Class属性值(Edit),在windows的窗口下,Parent属性的值中,括号里面的就表示它上一层元素的Class属性值,可以通过点击Parent属性值跳到上一层元素,最终我们定位到文件路径输入框的Class属性路径为:Edit - combox - comboBoxEx32 - #32770。

     

     那么同理,“打开”按钮通过同样的绝对路径方式定位,得到它的Class属性路径为:button - #32770。

     通过借助winspy工具定位出了对应元素的路径,就可以通过pywin32库来实现上传操作

  • 相关阅读:
    【数据结构】10.java源码关于LinkedHashMap
    【数据结构】9.java源码关于HashTable
    【数据结构】8.java源码关于HashMap
    【数据结构】7.java源码关于LinkedList
    【LEETCODE】69、动态规划,easy,medium级别,题目:198、139、221
    【LEETCODE】68、动态规划,medium级别,题目:95、120、91
    【LEETCODE】67、分治递归,medium&hard级别,题目:215、312
    【数据结构】6.java源码ArrayList
    【LEETCODE】66、字符串分类,hard级别,题目:32,72,76
    mysql查询所有表数据大小
  • 原文地址:https://www.cnblogs.com/zcok168/p/12651187.html
Copyright © 2020-2023  润新知