zoukankan      html  css  js  c++  java
  • python helium 安装使用

    前言. python自动化:Helium 是什么?

    Helium 是一款 Web 端自动化开源框架,全称是:Selenium-Python-Helium,从名字上就可以看出,Helium 似乎和 Selenium 息息相关

    确实,Helium 针对 Selenium 进行了封装,它屏蔽了 Selenium 很多实现细节,提供了更加简洁直观的 API,更方便我们进行 Web 端的自动化

    官方表示,要实现同样的功能,Helium 相比 Selenium 要少 30% - 50% 的代码

    目前,Helium 仅支持 Chrome 和 FireFox

    优缺点

    Helium 主要包含下面 6 个优点:

    • Helium 自带 WebDriver,不需要下载、配置浏览器驱动
    • 内嵌页面 iframe 页面元素直接操作,不需要使用 switch_to.frame() 切换 iframe
    • 窗体管理更方便,可以直接使用窗口标题或部分标题内容来切换窗体
    • 隐式等待,针对某个元素执行点击操作,Selenium 如果元素没有出现,脚本会执行失败;而 Helium 默认最多等待 10s,等待元素出现后立马执行点击操作
    • 显式等待,Helium 提供更加优雅的 API 来等待页面元素出现
    • API 更简洁直观,代码量少

    Helium 主要缺点,体现在:

    • 由于封装,屏蔽了很多细节,所以它不合适二次开发
    • 目前仅支持 Chrome 和 FireFox 浏览器
    • 版本更新慢、遗留 Bug 及文档少

    安装依赖

    pip3 install helium

    使用

    1. 启动浏览器

    def start_firefox(url=None, headless=False, options=None)

    • 这三个参数都有默认值,为None,所以都为可选填的

    url:要访问的网站网址

    headless:是否隐藏浏览器,即执行脚本时,浏览器是否可见

    options:浏览器配置,要使用options时需引入配置模块

    例子:

    start_firefox("google.com")
    start_chorme(headless=True)
    from selenium.webdriver import ChromeOptions
    #firefox引入FirefoxOptions
    options = ChromeOptions()
    options.add_argument('--start-maximized')
    options.add_argument('--proxy-server=1.2.3.4:5678')
    start_chrome("www.baidu.com",headless=True,options=options)
    
    • 和selenium 搭配,防止反爬系列
    def open_url():
    
    # 加启动配置
    options = webdriver.ChromeOptions()
    # 防止反爬
    options.add_experimental_option('useAutomationExtension', False)
    options.add_experimental_option('excludeSwitches', ['enable-automation'])
    driver = webdriver.Chrome(chrome_options=options)
    set_driver(driver)
    '''
    <script>
    if(window.navigator.webdriver == true){
    document.write("<span>看到这段就代表你是爬虫</span>")
    }else{
    document.write("<span>真正的信息在这儿呢</span>")
    }
    </script>
    '''
    go_to(r"file:///E:/auto_task/helium_test/test.html")
    time.sleep(5)
    

    访问网址

    def go_to(url)

    • 这个比较简单,直接用url即可

    写入

    def write(text, into=None)

    • 顾名思义,将内容写入输入框的功能,其中into为非必填,如果没填的话,默认输入到页面找到的第一个输入框,如果要填的话,对应的是element。
    options = ChromeOptions()
    options.add_argument("--start-maximized")
    start_chrome("https://www.zhihu.com/signin?next=%2F",options=options)
    click(Text("密码登录"))
    write("python@123.com",into=S("@username"))
    write("python",into="密码")
    write("royfans",TextField("Username"))
    # 大小写不敏感
    write("Zlf111",into="Password")
    write("test2",into=TextField(to_right_of="username"))
    
    click("Remember password")
    click("Log in")
    click(TextField("Site"))
    
    

    按键

    def press(key)

    • 普通字母数字直接用’key’就可以了,如果是特殊按键,这用对应的按键名即可,组合件的话,用+号连接
    press('A')
    press('a')
    press(ENTER)
    press(CONTROL + 'a')
    
    • 特殊按键对应的按键名可以在selenium.webdriver.common.keys.Keys找到。具体如下:
    NULL = Keys.NULL
    CANCEL = Keys.CANCEL
    HELP = Keys.HELP
    BACK_SPACE = Keys.BACK_SPACE
    TAB = Keys.TAB
    CLEAR = Keys.CLEAR
    RETURN = Keys.RETURN
    ENTER = Keys.ENTER
    SHIFT = Keys.SHIFT
    LEFT_SHIFT = Keys.LEFT_SHIFT
    CONTROL = Keys.CONTROL
    LEFT_CONTROL = Keys.LEFT_CONTROL
    ALT = Keys.ALT
    LEFT_ALT = Keys.LEFT_ALT
    PAUSE = Keys.PAUSE
    ESCAPE = Keys.ESCAPE
    SPACE = Keys.SPACE
    PAGE_UP = Keys.PAGE_UP
    PAGE_DOWN = Keys.PAGE_DOWN
    END = Keys.END
    HOME = Keys.HOME
    LEFT = Keys.LEFT
    ARROW_LEFT = Keys.ARROW_LEFT
    UP = Keys.UP
    ARROW_UP = Keys.ARROW_UP
    RIGHT = Keys.RIGHT
    ARROW_RIGHT = Keys.ARROW_RIGHT
    DOWN = Keys.DOWN
    ARROW_DOWN = Keys.ARROW_DOWN
    INSERT = Keys.INSERT
    DELETE = Keys.DELETE
    SEMICOLON = Keys.SEMICOLON
    EQUALS = Keys.EQUALS
    NUMPAD0 = Keys.NUMPAD0
    NUMPAD1 = Keys.NUMPAD1
    NUMPAD2 = Keys.NUMPAD2
    NUMPAD3 = Keys.NUMPAD3
    NUMPAD4 = Keys.NUMPAD4
    NUMPAD5 = Keys.NUMPAD5
    NUMPAD6 = Keys.NUMPAD6
    NUMPAD7 = Keys.NUMPAD7
    NUMPAD8 = Keys.NUMPAD8
    NUMPAD9 = Keys.NUMPAD9
    MULTIPLY = Keys.MULTIPLY
    ADD = Keys.ADD
    SEPARATOR = Keys.SEPARATOR
    SUBTRACT = Keys.SUBTRACT
    DECIMAL = Keys.DECIMAL
    DIVIDE = Keys.DIVIDE
    F1 = Keys.F1
    F2 = Keys.F2
    F3 = Keys.F3
    F4 = Keys.F4
    F5 = Keys.F5
    F6 = Keys.F6
    F7 = Keys.F7
    F8 = Keys.F8
    F9 = Keys.F9
    F10 = Keys.F10
    F11 = Keys.F11
    F12 = Keys.F12
    META = Keys.META
    COMMAND = Keys.COMMAND
    

    点击/双击/右击

    def click(element) #单击
    def doubleclick(element) #双击
    def rightclick(element)
    

    示例:

    click("Sign in")
    click(Button("OK"))
    click(Point(200, 300))
    click(ComboBox("File type").top_left + (50, 0))
    

    拖拽

    def drag(element, to)

    • 将一个元素拖拽到指定位置,这个个人使用时,自己用elment-ui写了个drag功能一直拖拽失败,比较尴尬。
      官方示例:

    drag("Drag me!", to="Drop here.")

    拖拽文件

    def drag_file(file_path, to)

    将本地的文件拖入到浏览器指定的位置,挺好用的一个功能。
    示例:

    click("配置管理")
    wait_until(Text("文件上传").exists)
    click("文件上传")
    drag_file(r"D:\1.jpg",to="将文件拖到此处,或点击上传")
    

    上传文件

    def attach_file(file_path, to=None)

    • 将文件上传,这个针对的是input type=“file”
      示例:
    start_chrome("file:///D:/1.html",options=options)
    attach_file(r"D:\2.jpg")
    

    按住/松开左键

    def press_mouse_on(element)
    def release_mouse_over(element)

    鼠标悬浮

    def hover(element)

    示例:

    hover("File size")
    hover(Button("OK"))
    hover(Link("Download"))
    hover(Point(200, 300))
    hover(ComboBox("File type").top_left + (50, 0))
    hover("任务中心")
    click("任务查询")
    
    

    向上/下/左/右滚动屏幕

    def scroll_down(num_pixels=100)
    def scroll_up(num_pixels=100)
    def scroll_right(num_pixels=100)
    def scroll_left(num_pixels=100)
    

    不设置参数时默认为100像素,设置参数的话直接写数字就可以

    查找元素组

    def find_all(predicate)

    这个比较简单,就是找元素组,然后根据index来取元素。示例:

    find_all(Button("Open"))
    find_all(Window())
    find_all(TextField("Address"))
    find_all(Text("进入"))
    click(find_all(Text("进入"))[0])
    # 有相同的placehold,用find_all 查找全部元素
    p = find_all(TextField("Please select"))
    click(p[0])
    
    

    下拉框选择

    def select(combo_box, value)

    从下拉选项中选择一项,示例:

    select("Language", "English")
    select(ComboBox("Language"), "English")
    

    刷新页面

    def refresh()

    直接使用即可

    等待元素

    def wait_until(condition_fn, timeout_secs=10, interval_secs=0.5)

    等待某个条件为真才继续往下执行。默认的超时时间为10s,每0.5查询一次,这俩参数选填。可以设置超时时间和轮询间隔。

    注意:condition_fn等待条件直接采用函数的话,不能带()或者直接用lambda后带完整函数。

    示例:

    wait_until(Text("Finished!").exists)
    wait_until(lambda:Text("Finished!").exists())
    

    配置文件—隐式等待时间

    等待时间:
    首先要知道隐式等待时间的含义,是指执行脚本时,如果某个元素元素刚开始没找到,会默认等待一段时间,超时后才会抛出错误。显示等待这是直接在代码里写等待多久,比如time.sleep(xxx)

    • 配置管理:
      helium中有个Config类

    class Config:

    里面只介绍了隐式等待时间的设置。默认值为10s,如果要自己设置,直接调用config即可:
    在这里插入图片描述如果要关闭隐式等待时间,则只需要将时间设置为0即可。

    onfig.implicit_wait_secs(10)

    UI基础类: class GUIElement

    最基础的UI类,用的上的只有一个函数

    def exists(self)

    用于判断某个元素是否存在,返回true或false

    元素基础类:class HTMLElement(GUIElement)

    界面元素类,继承GUIElement,有六个属性:

    width #元素宽度
    height #高度
    x #元素在界面上的X轴坐标
    y #y轴坐标 
    top_left #元素坐上角的坐标
    web_element #转换为web_element,之后可以调用selenium元素的属性和方法
    
    start_chrome("file:///D:/1.html",options=options)
    element = Button("submit")
    width = element.width
    height = element.height
    x = element.x
    y = element.y
    top_left = element.top_left
    web_el_text = element.web_element.text
    web_el_tag = element.web_element.tag_name
    print("元素大小:{width}*{height},元素位置:{x},{y},元素左上角位置:{top_left},元素文本:{web_el_text},元素类别:{web_el_tag}".format(
    width = width,
    height = height,
    x = x,
    y = y,
    top_left = top_left,
    web_el_text = web_el_text,
    web_el_tag = web_el_tag
    
    ))
    

    结果如下图,可以发现x,y实际就是top_left的具体坐标值,而top_left的返回类型为Point,所以要对top_left做位置变换需要用Point数据:

    元素大小:85*26,元素位置:1407,146,元素左上角位置:Point(x=1407, y=146),元素文本:Search,元素类别:button

    此外,要关注一下__init__方法,也就是类的初始化:

    def __init__(self, below=None, to_right_of=None, above=None, to_left_of=None)
    1
    这个是说在可以通过相对位置来实现元素及控件的查找
    
    below #在某个元素下方
    above #在某个元素上方
    to_right_of #在某个元素右侧
    to_left_of #在某个元素左侧
    所有基于HTMLElement类的元素或者控件都可以通过这4个相对位置来实现元素查找。
    例子:
    
    Button("登录",below="password") #位于password下的登录按钮
    

    元素定位类:class S(HTMLElement)

    它是基于HTMLElement的,不同定位方式是通过符号来区分的
    
    @ #对应name
    . #对应class
    # #对应id
    // #对应xpath或者css selector
    
    示例:
    
    write("testname",into=S("#username"))
    find_all(S("table > tr > td", below="Email"))
    write("abc",into=S("[type=text]"))
    
    

    Helium比较特殊,元素定位类是继承HTMLElement的,而其他控件,比如Button、Link等也全都继承HTMLElement,所以这几个是并列关系,也就是说

    控件无法通过定位类S来实现控件查找,只能基于控件文本和HTMLElement中的四个相对位置来实现控件查找

    比如Button(S("#submit")是错误的,可以通过Button(“登录”,below=“username”)来实现查找。

    控件类

    所有控件类都继承HTMLElement类,所以可以试用HTMLElement和GUIElement类的方法与属性。

    1. 文本控件
      用于获取界面文本的控件,拥有value属性来获取控件对应的文本
    class Text(HTMLElement)
    @property
    def value(self)
    

    示例

    Text("Do you want to proceed?").exists()
    Text(below="Email", to_right_of="John").value
    
    1. 链接控件
      用于识别界面上的链接,拥有href属性可以获取链接对应的url
    class Link(HTMLElement)
    @property
    def href(self)
    

    示例:

    click(Link("Block User", to_right_of="John Doe"))
    Link("百度").href

    3.序列控件
    可以获取界面上的序列

  • 元素

    class ListItem(HTMLElement)

    示例:

    click(ListItem("List item 1", below="My first list:"))
    assert ListItem("List item 1").exists()
    ListItem("Account Resource").exists()
    
    

    4.按钮控件
    可以获取按钮控件,具有is_enabled方法,用于判断按钮是否有被disabled

    class Button(HTMLElement)
    def is_enabled(self)
    

    示例:

    click(Button("OK"))
    click(Button("Log In", below=TextField("Password")))
    Button("OK").is_enabled()
    

    5.图片控件

    识别图片元素,从__init__类的初始化函数可以看到相对其他控件的text=None(,图片控件的是alt=None,也就是说要通过alt而非text来识别图片,至于什么是alt,这个是html基础,不懂得可以百度。

    class Image(HTMLElement)
    def __init__(self, alt=None, below=None, to_right_of=None, above=None,to_left_of=None)
    

    示例:

    click(Image(alt="logo"))
    lick(Image("logo", to_left_of=ListItem("Download")))
    Image("logo").exists()
    

    6.文本框控件

    可识别可以用于输入的文本框控件,它是通过label加相对位置来定位的,这个label既可以采用本文框左侧的文字,也可以采用文本框内部的提示语,也就是html的placeholder里的文本。
    value属性,可以获取文本框里的文本;
    is_enabled()方法,识别文本框是否被disabled,界面上显示的就是置灰
    is_editable()方法,识别文本框是否可编辑,也就是是否有配置readonly,这时控件是不置灰的,但是不可编辑。

    class TextField(HTMLElement)
    def __init__(self, label=None, below=None, to_right_of=None, above=None,to_left_of=None)
    @property
    def value(self)
    
    def is_enabled(self)
    
    def is_editable(self)
    

    示例:
    html代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <h1>hello worlds</h1>
    username:<input placeholder="请输入用户名"></input>
    </body>
    </html>
    

    自动化代码如下:

    from helium import *
    from selenium.webdriver import ChromeOptions
    import time
    Config.implicit_wait_secs=30
    
    options = ChromeOptions()
    options.add_argument("--start-maximized")
    start_chrome("file:///D:/1.html",options=options)
    write("test1",into=TextField("username"))
    time.sleep(3)
    write("test2",into=TextField(to_right_of="username"))
    time.sleep(3)
    write("test3",into=TextField("请输入用户名"))
    element = Button("submit")
    

    上面3种方式都是可以找到input控件的,都可以成功输入。

    7.下拉列表框控件
    这个相对select来说范围更广,一般来说既可以指的select,也可以指dropdown控件,特别是一些可以通过输入文本来匹配选项的控件,都可以用这个控件。
    查看__init__可以发现跟文本框是一样的,都是用label来识别控件,查找方法类似上面文本框控件。它本身经常和select一起使用,用于选中某一选项。
    value属性:可以获取已选中项的值
    options属性:可以获取所有可以选择的选项内容
    is_editable()方法:判断是否可输入文本来匹配选项

    class ComboBox(HTMLElement)
    def __init__(self, label=None, below=None, to_right_of=None, above=None,to_left_of=None)
    
    def is_editable(self)
    
    @property
    def value(self)
    
    @property
    def options(self)
    

    示例:

    ComboBox("Language").value
    select(ComboBox(to_right_of="John Doe", below="Status"), "Active")
    

    8.复选框控件
    顾名思义,识别复选框用的。
    is_enabled()方法:判断是否被disabled
    is_checked()方法:判断是否被选中

    class CheckBox(HTMLElement)
    def __init__(self, label=None, below=None, to_right_of=None, above=None,to_left_of=None)
    
    def is_enabled(self)
    
    def is_checked(self)
    

    示例:

    CheckBox("已阅读xx").is_checked()
    click(CheckBox("记住登录状态", below=Button("登录")))
    

    9.单选框控件
    单选框专用
    is_selected()方法:判断是否被选中

    class RadioButton(HTMLElement)
    def __init__(self, label=None, below=None, to_right_of=None, above=None,to_left_of=None)
    
    def is_selected(self)
    

    示例:

    RadioButton("Windows").is_selected()
    click(RadioButton("我同意", below="用户协议"))
    

    弹窗Alert

    这个是专门针对alert弹窗的,是继承GUIElement的,所以没法用四个相对位置来查找,不过一般alert都会位于界面最顶层,所以一般也比较容易识别出来。
    通过__init__可以知道它可以通过文本来查找弹窗,特别是对于多个弹窗的话,用文本来区分即可,如果只有一个弹窗,可以search_text放空一般也可以找到
    text属性:获取弹窗上的文本内容
    accept()方法:相当于点击弹窗上的OK / 确认键
    dismiss()方法:相当于点击弹窗上的Cancel / 取消按键

    class Alert(GUIElement)
    def __init__(self, search_text=None)
    
    @property
    def text(self)
    
    def accept(self)
    
    def dismiss(self)
    

    示例:

    write("12",into=Alert("请输入个数"))
    Alert().accept()
    Alert().dismiss()
    

    坐标点Point

    通过x,y来表示元素在界面上的具体坐标,如果要偏移位置,可以用+或者-来实现。

    class Point(namedtuple('Point', ['x', 'y']))
    def __init__(self, x=0, y=0)
    
    @property #X轴坐标
    def x(self)
    
    @property #Y轴坐标
    def y(self)
    
    def __eq__(self, other) # 对比两个Point看是否相等
    
    def __ne__(self, other) # 对比两个Point看是否相等
    
    def __hash__(self) #hash,返回x + 7*y,暂时未知作用
    
    def __add__(self,delta) #相加,delta对应某个point
    
    def __radd__(self,delta) #功能和add一致,为啥叫radd未知
    
    def __sub__(self,delta) #相减
    
    def __rsub__(self,delta) #相减,同sub一样
    

    示例:

    print(Point(100,100)+ (Point(1,2)))
    print(Point(100,100).__add__(Point(1,2)))
    

    窗口

    可以用于或者窗口title也可以配合switch_to来进行窗口的切换

    class Window(GUIElement)
    def __init__(self, title=None)
    
    @property #窗口的title
    def title(self)
    
    @property #返回selenium driver的标识,本身不具备操控界面的能力
    def handle(self)
    

    示例:

    print(Window().title)
    switch_to(Window("标题"))
    switch_to(find_all(Window())[0])
    

    窗口切换switch_to

    通过窗口的title来切换窗口

    def switch_to(window)

    示例:

    switch_to("Google")
    switch_to(Window("Google"))
    switch_to(find_all(Window())[0])
    

    关掉浏览器

    就是单纯的关掉浏览器,如果不调用该方法,执行完后浏览器会保持打开状态

    def kill_browser()

    高亮highlight

    为了凸显某一元素便于查看或者在操作某一元素前,可以采用highlight来标识出来,然后再采用截图的话,可以明确知道该步骤在页面上对哪个元素进行操作。

    def highlight(element)

    示例:

    highlight(TextField("username"))

    与selenium配合(set_driver/get_driver)

    set_driver(driver)用于将selenium的driver切换到helium,这样就可以直接使用helium的api了
    get_driver()用于获取helium的driver,然后driver后可以使用selenium语句

    从selenium到helium:

    from selenium import webdriver
    from helium import *
    driver = webdriver.Chrome()
    set_driver(driver)
    go_to("http://127.0.0.1:8080/#/login")
    

    从helium到selenium:

    from helium import *
    start_chrome()
    driver = get_driver() #或者直接driver = start_chrome()
    element = driver.find_element_by_id('auto_test')
    print(element.text)
    driver.save_screenshot("D:/1.png")
    

    实战应用

    1.时间选择:

    click(TextField("added at"))
    click("17")
    click("17")
    click('ok')
    

    2. 搜索下拉选择

    ListItem("Account Resource").exists()

    参考:

查看全文
  • 相关阅读:
    ibatis $与#的区别
    (转载)Hibernate与Jpa的关系
    tomcat web工程 jar包冲突解决方法
    jquery 获取checkbox 选中值并拼接字符集
    mysql BLOB字段转String的方法
    Ajax工作原理
    Spring mvc 具体RequestMapping 参数含义
    覆盖bootstrap的样式
    开园啦,致曾经现在以后的自己~
    SimpleDateFormat 常规用法
  • 原文地址:https://www.cnblogs.com/royfans/p/14261859.html
  • Copyright © 2011-2022 走看看