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

    參考:


  • 免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM