• selenium基础操作


    selenium

    1、打开和关闭网页

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from selenium import webdriver
    
    driver = webdriver.Firefox()
    # 也可指定驱动和浏览器
    # binary = FirefoxBinary('/usr/bin/firefox')
    # driver = webdriver.Firefox(firefox_binary=binary, executable_path="/home/zk/scrapy_dazhong/geckodriver")
    
    # 设置初始坐标位置
    driver.set_window_position(x=500, y=60)
    
    # 设置窗口大小
    # driver.set_window_size(width=300, height=200)
    
    # 将浏览器最大化显示
    driver.maximize_window()
    
    # 打开浏览器并输入网址
    driver.get("http://www.baidu.com")
    
    # 后退访问页
    # driver.back()
    # 前进访问页
    # driver.forward()
    
    time.sleep(10)
    
    # close()用于关闭当前窗口,quit()用于退出驱动程序并关闭所有相关窗口.
    driver.quit()
    
    # 关闭浏览器
    # driver.close()
    

    2、获取信息

    # 获取页面title
    now_title = driver.title
    print now_title
    # 获取当前url
    now_url = driver.current_url
    print now_url
    # 获取页面详情代码(HTML)
    print driver.page_source
    

    3、查找元素

    """
    在webdriver中,支持的找元素的方法有
    查找方法                                        对应元素
    find_element_by_id                       id
    find_element_by_name                 name
    find_element_by_class_name         class name
    find_element_by_tag_name           tag name
    find_element_by_link_text             link text
    find_element_by_partial_link_text   partial link text
    find_element_by_xpath                 xpath
    find_element_by_css_selector         css selector
    """
    # 根据Id获取标签
    inputelement = driver.find_element_by_id('kw')
    
    # 清除输入框内容
    inputelement.clear()
    
    # 输入框输入信息
    inputelement.send_keys("biubiubiu")
    
    # 触发点击事件
    driver.find_element_by_id('su').click()
    
    # 通过 submit() 来提交操作
    driver.find_element_by_id("dl_an_submit").submit()
    
    # 获取百度输入框的宽高
    size=driver.find_element_by_id("kw").size
    print size
    
    # 获取百度底部的文本信息
    text=driver.find_element_by_id("cp").text
    print text
    
    # 获取元素的属性值,可以是 id、name、type 或元素拥有的其它任意属性
    attribute=driver.find_element_by_id("kw").get_attribute('type')
    print attribute
    
    # 获取元素的结果是否可见,返回结果为 True 或 False
    result=driver.find_element_by_id("kw").is_displayed()
    print result
    

     4、鼠标操作

    """
    ActionChains 类鼠标操作的常用方法:
        context_click() 右击
        double_click() 双击
        drag_and_drop() 拖动
        move_to_element() 鼠标悬停在一个元素上
        click_and_hold() 按下不放鼠标左键在一个元素
        release()   在某个元素上释放鼠标
    """
    # 定位元素
    right =driver.find_element_by_xpath("kw")
    
    # 对定位到的元素执行鼠标右键操作
    ActionChains(driver).context_click(inputelement).perform()
    
    # 对定位到的元素执行鼠标双击操作
    ActionChains(driver).double_click(inputelement).perform()
    
    # ####鼠标拖动####
    # 定位元素的原位置
    element = driver.find_element_by_id("lg")
    # 定位元素要移动到的目标位置
    target = driver.find_element_by_class_name("qrcode-img")
    # 执行元素的移动操作
    ActionChains(driver).drag_and_drop(element, target).perform()
    
    time.sleep(3)
    su = driver.find_element_by_id("su")
    # 对定位到的元素执行鼠标移动到上面的操作
    ActionChains(driver).move_to_element(su).perform()
    time.sleep(3)
    # 对定位到的元素执行鼠标左键按下不放的操作
    ActionChains(driver).click_and_hold(su).perform()
    # 在指定元素上释放鼠标
    ActionChains(driver).release(su)
    

     实例:

    # -*- coding: utf-8 -*-
    
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from time import sleep
    import random
    
    driver = webdriver.Firefox()
    driver.implicitly_wait(10)
    driver.maximize_window()
    driver.get('http://sahitest.com/demo/dragDropMooTools.htm')
    
    dragger = driver.find_element_by_id('dragger')  # 被拖拽元素
    item1 = driver.find_element_by_xpath('//div[text()="Item 1"]')  # 目标元素1
    item2 = driver.find_element_by_xpath('//div[text()="Item 2"]')  # 目标2
    item3 = driver.find_element_by_xpath('//div[text()="Item 3"]')  # 目标3
    item4 = driver.find_element_by_xpath('//div[text()="Item 4"]')  # 目标4
    # action = ActionChains(driver)
    # 按下鼠标不放
    ActionChains(driver).click_and_hold(on_element=dragger).perform()
    sleep(3)
    for i in range(1, 50):
        print "--->i", i
        # 移动 110
        ActionChains(driver).move_to_element_with_offset(to_element=dragger, xoffset=60, yoffset=55).perform()
        sleep(random.randint(3, 5)/100)
    # 释放鼠标
    ActionChains(driver).release(on_element=dragger).perform()
    
    # action = ActionChains(driver)
    # action.drag_and_drop(dragger, item1).perform()  # 1.移动dragger到目标1
    # sleep(2)
    # action.click_and_hold(dragger).release(item2).perform()  # 2.效果与上句相同,也能起到移动效果
    # sleep(2)
    # action.click_and_hold(dragger).move_to_element(item3).release().perform()  # 3.效果与上两句相同,也能起到移动的效果
    # sleep(2)
    # action.drag_and_drop_by_offset(dragger, 400, 150).perform()  # 4.移动到指定坐标
    
    # action.click_and_hold(dragger).move_by_offset(400, 150).release().perform()  # 5.与上一句相同,移动到指定坐标
    # sleep(2)
    # driver.quit()
    
    # 借鉴其它大神的代码!!!具体忘记在哪看到的了,如有侵权,请告知,立改
    

     5、键盘操作

    """
    常用
    send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
    send_keys(Keys.SPACE) 空格键(Space)
    send_keys(Keys.TAB) 制表键(Tab)
    send_keys(Keys.ESCAPE) 回退键(Esc)
    send_keys(Keys.ENTER) 回车键(Enter)
    send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
    send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
    send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
    send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)
    Keys 类所提供的按键请查阅 webdriver API
    """
    
    # 输入框输入内容
    driver.find_element_by_id("kw").send_keys("selenium")
    time.sleep(3)
    # 删除最后一个字符
    driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
    time.sleep(3)
    # 输入空格键+“教程”
    driver.find_element_by_id("kw").send_keys(Keys.SPACE)
    driver.find_element_by_id("kw").send_keys(u"教程")
    time.sleep(3)
    # ctrl+a 全选输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'a')
    # ctrl+x 剪切输入框内容
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'x')
    time.sleep(3)
    # 输入框重新输入内容,搜索
    driver.find_element_by_id("kw").send_keys(Keys.CONTROL, 'v')
    time.sleep(3)
    # 通过回车键盘来代替点击操作
    driver.find_element_by_id("su").send_keys(Keys.ENTER)
    

     6、设置超时时间

    """
    sleep():设置固定休眠时间.python的time 包提供了休眠方法sleep(),导入time包后就可以使用sleep(),进行脚本的执行过程进行休眠.
    implicitly_wait():是 webdirver 提供的一个超时等待.隐示等待一个元素被发现,或一个命令完成.如果超出了设置时间的则抛出异常.
    WebDriverWait():同样也是 webdirver 提供的方法.在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常.
    """
    # 隐示等待:implicitly_wait
    # 相当于设置全局的等待,在定位元素时,对所有元素设置超时时间,超出了设置时间则抛出异常
    # 隐式等待使得WebDriver在查找一个Element或者Element数组时,每隔一段特定的时间就会轮询一次DOM,如果Element或数组没有马上被发现的话。
    # 默认设置是0。
    # 一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用
    driver.implicitly_wait(10)
    
    # WebDriverWait主要提供了两个方法,一个是until()(元素出现), 另外一个是until_not()(元素消失)
    # until(method, message=’’)
    # 调用该方法提供的驱动程序作为一个参数,直到返回值不为 False。
    # until_not(method, message=’’)
    # 调用该方法提供的驱动程序作为一个参数,直到返回值为 False
    
    # 等待时长10秒,默认0.5秒询问一次
    WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("kw")).send_keys("yoyo")
    time.sleep(3)
    # 判断id为kw元素是否消失,设置等待时长10秒,询问时间为1秒
    is_disappeared = WebDriverWait(driver, 10, 1).until_not(lambda x: x.find_element_by_id("kw").is_displayed())
    print is_disappeared
    

     7、定位一组对象

    """
    使用场景:
        批量操作对象,比如将页面上所有的 checkbox 都勾上
        先获取一组对象,再在这组对象中过滤出需要具体定位的一些对象.比如定位出页面上所有的 checkbox,然后选择最后一个.
    * find_elements 用于获取一组元素
    元素存储在list中,可进行任意操作
    """
    # 选择页面上所有的 tag name 为 input 的元素
    inputs = driver.find_elements_by_tag_name('input')
    # 选择页面上所有的 css name 为 input 的元素
    inputs_ = driver.find_elements_by_css_selector('input[type=checkbox]')
    # 然后从中过滤出type为checkbox 的元素,单击勾选
    for item in inputs:
        if item.get_attribute('type') == 'checkbox':
            item.click()
    

     8、层级定位

    menu = driver.find_element_by_id('login-ul').find_element_by_link_text(u'关闭的项目').click()
    

     实例:

    # 设置等待(low的办法)
    tmp = 10
    while tmp > 0:
        time.sleep(3)
        result = driver.find_element_by_link_text(u"立即体验").is_displayed()
        print result
        tmp -= 1
        if result:
            driver.find_element_by_link_text(u"立即体验").click()
            time.sleep(10)
            tmp = 0
    
    # 设置等待(较为方便)
    # WebDriverWait(driver, 30).until(lambda driver: driver.find_element_by_link_text(u"立即体验").is_displayed())
    # driver.find_element_by_link_text(u"立即体验").click()
    
    print u"已跳转页面%s" %driver.current_url
    
    button_ = driver.find_elements_by_css_selector('button[data-toggle="dropdown"]')
    button_[0].click()
    # 在父亲元件下找到 link 为 Action 的子元素
    time.sleep(2)
    # 层级定位,先找到login-ul的列表,在找到列表的某个元素
    menu = driver.find_element_by_id('login-ul').find_element_by_link_text(u'关闭的项目').click()
    # 找到元素直接click与下方方法结果一致
    ActionChains(driver).click(menu).perform()
    

     9、IFrame标签

    """
    在 web 应用中经常会出现 frame 嵌套的应用,假设页面上有 A、B 两个 frame,
    其中 B 在 A 内,那么 定位 B 中的内容则需要先到 A,然后再到 B.
    switch_to_frame 方法可以把当前定位的主体切换了 frame 里
    """
    # 进入到iframe标签里
    driver.switch_to_frame(name="login_frame")
    

     实例:自动化登陆QQ邮箱,并获取所有的邮件标题的示例

    # 找到iframe中
    driver.switch_to_frame(name="login_frame")
    # 在当前iframe中匹配
    user = driver.find_element_by_xpath(".//*[@id='u']")
    user.send_keys("帐号")    # 输入你的账号
    time.sleep(1)
    password = driver.find_element_by_xpath(".//*[@id='p']")
    password.send_keys("密码")    # 输入你的密码
    time.sleep(2)
    driver.find_element_by_xpath(".//*[@id='login_button']").click()    # 点击登陆按钮
    
    print u"已跳转页面%s"%driver.current_url
    time.sleep(5)
    
    # selenium.common.exceptions.WebDriverException: Message: TypeError: can't access dead object
    # 解决报错方法
    driver.switch_to_default_content()
    # time.sleep(3)
    
    # QQ邮箱有独立密码设置的,需要增加此步骤,没有可以省略
    js = 'document.getElementById("pp").setAttribute("_focus","1");'
    driver.execute_script(js)
    time.sleep(2)
    # 匹配独立密码输入框
    duli_pwd = driver.find_element_by_id("pp")
    duli_pwd.send_keys("密码")    # 输入你的独立密码
    # 点击独立密码登陆按钮
    driver.find_element_by_xpath(".//*[@id='btlogin']").click()
    time.sleep(2)
    print u"已跳转页面%s"%driver.current_url
    time.sleep(2)
    # #######################登陆成功后##################################
    # 登陆后点击收件箱
    driver.find_element_by_xpath(".//*[@id='folder_1']").click()
    # 切入邮箱的IFrame中
    driver.switch_to_frame("mainFrame")
    time.sleep(5)
    
    def test():
        # 获取网页信息
        content = driver.page_source
        # lxml
        content_ = etree.HTML(content)
        # 查找是否有下一页的标签
        next_page = content_.xpath(".//*[@id='nextpage1']/text()")
        if not next_page:
            return
        # 未读邮件列表
        if_mail_list = content_.xpath(".//*[@class='i F']")
        # 已读邮件列表
        im_mail_list = content_.xpath(".//*[@class='i M']")
        for item in if_mail_list:
            from_name = item.xpath("./tbody/tr/td[3]/table/tbody/tr/td[1]/nobr/span/text()")
            main_ = item.xpath("./tbody/tr/td[3]/table/tbody/tr/td[3]/div[1]/u/text()")
            print u"未读--->", u"来自:", from_name[0].strip() if from_name else u"哦...", u"主题:", main_[0].strip() if main_ else u"没..."
    
        for item in im_mail_list:
            from_name = item.xpath("./tbody/tr/td[3]/table/tbody/tr/td[1]/nobr/span/text()")
            main_ = item.xpath("./tbody/tr/td[3]/table/tbody/tr/td[3]/div[1]/u/text()")
            print u"已读--->", u"来自:", from_name[0].strip() if from_name else u"哦...", u"主题:", main_[0].strip() if main_ else u"没..."
        time.sleep(3)
        # 点击下一页
        driver.find_element_by_xpath(".//*[@id='nextpage1']").click()
        time.sleep(3)
        test()
    if __name__ == '__main__':
        test()
    

    10、多窗口操作

    """
    要想在多个窗口之间切换,首先要获得每一个窗口的唯一标识符号(句柄)通过获得的句柄来区别
    分不同的窗口,从而对不同窗口上的元素进行操作
    window_handles #返回的所有窗口的句柄到当前会话
    switch_to_window() # 获得当前窗口
    用于处理多窗口操作的方法,与我们前面学过的 switch_to_frame() 是类似,switch_to_window()用于 处理多窗口之前切换,switch_to_frame() 用于处理多框架的切换。# nowhandle=driver.current_window_handle# driver.find_element_by_xpath(".//*[@id='u1']/a[7]").click()
    """
    time.sleep(5)# print u"当前窗口", nowhandle# 打开注册新窗口
    driver.find_element_by_xpath(".//*[@id='TANGRAM__PSP_10__submitWrapper']/a[1]").click()
    time.sleep(3)
    driver.implicitly_wait(3)
    allhandles=driver.window_handles
    print u"所有窗口", allhandles
    # 循环判断窗口是否为当前窗口
    for handle in allhandles:
        if handle != nowhandle:
    #         跳转窗口
            driver.switch_to_window(handle)
            print 'now register window!'
            # 切换到邮箱注册标签
            driver.close()
    # 回到原先的窗口
    driver.switch_to_window(nowhandle)
    driver.find_element_by_id("kw").send_keys(u"注册成功!")
    

     11、alert/confirm/prompt操作

    """
    alert(弹框)/confirm(弹框带确认取消按钮)/prompt(带输入框的弹框)
    
    text 返回 alert/confirm/prompt 中的文字信息
    accept 点击确认按钮
    dismiss 点击取消按钮,如果有的话
    send_keys 输入值,这个 alertconfirm 没有对话框就不能用了,不然会报错
    """
    # 进入iframe标签
    driver.switch_to_frame("i")
    time.sleep(5)
    # 找到按钮点击
    driver.find_element_by_xpath("html/body/input").click()
    time.sleep(3)
    # 获取网页上的警告信息
    alert_obj = driver.switch_to_alert()
    time.sleep(2)
    # 取警告信息,不能+()
    print alert_obj.text
    # 输入值(如果有的话)
    alert_obj.send_keys("abc")
    time.sleep(2)
    # 点击确认按钮
    alert_obj.accept()
    # 点击取消按钮(如果有的话)
    alert_obj.dismiss()
    

     12、文件上传

    driver.implicitly_wait(3)
    # 定位上传按钮,添加本地文件
    file_path = '/home/zk/testsub/abc.txt'
    # send_keys 不仅可以写入信息,也可以上传文件
    driver.find_element_by_xpath(".//*[@id='post-5071']/div/ol[3]/li[4]/label").send_keys(file_path)
    time.sleep(2)
    

     13、文件下载

    只是大致尝试了一下,具体情况等待以后有需求在测试
    """
    browser.download.dir 用于指定你所下载文件的目录
    os.getcwd() 该函数不需要传递参数,用于返回当前的目录
    application/octet-stream 为内容的类型
    """
    import os
    fp = webdriver.FirefoxProfile()
    fp.set_preference("browser.download.folderList", 2)
    fp.set_preference("browser.download.manager.showWhenStarting", False)
    fp.set_preference("browser.download.dir", os.getcwd())
    fp.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream")
    browser = webdriver.Firefox(firefox_profile=fp)
    browser.get("https://pypi.python.org/packages/d0/b1/1c9d9cc3fd6c1cd802d897d78a9ea5ad01b07c6c0f422b235717b74270ae/selenium-3.7.0-py2.py3-none-any.whl#md5=52fc71d16b86204e467002c1930d7b65")
    browser.find_element_by_xpath(".//*[@id='post-5071']/div/ol[3]/li[4]/label").click()
    

     14、执行JS

    """
    webdriver 提供了 execute_script() 接口用来调用 js 代码。
    执行 JS 一般有两种场景:
        1:一种是在页面上直接执行 JS
        2:另一种是在某个已经定位的元素上执行 JS
    execute_script(script, *args)
    在当前窗口/框架 同步执行 javaScript
    script:JavaScript 的执行。
    *args:适用任何 JavaScript 脚本
    """
    # ######通过 JS 隐藏选中的元素##########第一种方法:
    # 隐藏文字信息
    driver.execute_script('$("#tooltip").fadeOut();')
    time.sleep(5)
    # 隐藏按钮:
    button = driver.find_element_by_class_name('btn')
    driver.execute_script('$(arguments[0]).fadeOut()',button)
    

    实例:滑动滚动条

    driver.find_element_by_id("kw").send_keys("selenium")
    driver.find_element_by_id("su").click()
    time.sleep(3)
    # 将页面滚动条拖到底部
    js="var q=document.documentElement.scrollTop=10000"
    driver.execute_script(js)
    time.sleep(3)
    # 将滚动条移动到页面的顶部
    js_="var q=document.documentElement.scrollTop=0"
    driver.execute_script(js_)
    time.sleep(3)
    

     15、cookie操作

    """
    webdriver 操作 cookie 的方法有:
        get_cookies() 获得所有 cookie 信息
        get_cookie(name) 返回特定 name 有 cookie 信息
        add_cookie(cookie_dict) 添加 cookie,必须有 name 和 value 值
        delete_cookie(name) 删除特定(部分)的 cookie 信息
        delete_all_cookies() 删除所有 cookie 信息
    """
    # 把cookie保存到本地
    post = {}
    cookie_items = driver.get_cookies()
    for cookie_item in cookie_items:
        post[cookie_item['name']] = cookie_item['value']
    cookie_str = json.dumps(post)
    with open('cookie.txt', 'w') as f:
        f.write(cookie_str)
    print("cookies信息已保存到本地")
    
    # 取出cookie
    with open('cookie.txt', 'r', encoding='utf-8') as f:
        cookie = f.read()
    cookies = json.loads(cookie)
    
  • 相关阅读:
    Excel导出失败的提示
    C#中将一个引用赋值null的作用
    POJ2112Optimal Milking(二分法+floyd最短+网络流量)
    三年流水账
    OpenCV(C++接口)学习笔记1-图像读取、显示、保存
    thinkphp3.2 代码生成并点击验证码
    8.19! 今天我有18生日,点击阅读或顶部 尾随幸运的一天!生日知识!↓——【Badboy】
    如何系统地学习JavaScript
    HDU 3065 病毒在继续 (AC自己主动机)
    使用Canvas和Paint自己绘制折线图
  • 原文地址:https://www.cnblogs.com/shangpolu/p/7929689.html
Copyright © 2020-2023  润新知