Golang使用selenium操作Chrome

Golang使用selenium操作Chrome

1.需求

​ 解決自動化登錄的問題,順便可以解決爬蟲問題。

2.基本概念

​ selenium: Selenium 是一個用於 Web 應用程序測試的工具,Selenium 測試直接自動運行在瀏覽器中,就像真正的用戶在手工操作一樣。

​ webdriver: chromeDriver是谷歌爲網站開發人員提供的自動化測試工具。

​ selenium和webdriver其實原來是兩個不同的開源項目,後來selenium2就把selenium1(RC)和webdriver合併到一起,還是用selenium的名字,但是實現方式和協議基本沿用的是webdriver的。可以看做一樣。

簡單來說,需要通過chromedriver調用chrome,進行模擬瀏覽器操作。

3.安裝

  • 下載chromedriver。chrome和chromedriver 要版本對應,chromedriver版本下載,放到相應目錄。

  • 下載golang代碼包。selenium的golang代碼包

    go get -t -d github.com/tebeka/selenium
  • 注意點: 本人Win10,調用chrome報錯。主要涉及3個點: 1.將chrome添加至環境變量path中,可以通過cmd直接運行chrome.exe確定是否運行成功;2.修改程序的權限,讓執行賬戶獲取所有權,避免權限提升 3.如果提示沒有找到google-chrome時,拷貝一份chrome.exe重命名爲google.chrome.exe。

4.源碼分析

4.1 selenium執行流程分析

​ 經過我的理解和思考,我認爲selenium 主要運行模式如下(個人理解,僅供參考)。

image.png

​ 程序需要調用selenium庫執行相應的函數, 後臺調用chrome瀏覽器,然後將操作元素的請求給下方的瀏覽器驅動。瀏覽器驅動再轉發這個請求給瀏覽器。最後將結果返回。

4.2 源碼文件分析selenium-golangdoc

​ 因爲selenium源碼包不是很大,同時因爲是chrome進行實戰,所以我將源碼進行刪減然後進行添加註釋。godoc包應該沒有寫完整,比如webdriver,webelement只講了接口,並沒有將實現細節,我們可以根據selenium操作進行腦補。可以參考python中selenium中的實現,比如自動化測試

​ 先繼續畫個圖進行包的講解的吧。

image.png

​ 源碼簡略分析:

// 第一類 雜項

//刪除會話
func DeleteSession(urlPrefix, id string) error

//開啓關閉debug調試
func SetDebug(debug bool)

//設置代理
func (c Capabilities) AddProxy(p Proxy)
//設置日誌級別
func (c Capabilities) SetLogLevel(typ log.Type, level log.Level)

// 第二類 seleium後臺服務

//服務實例的可選項
type ServiceOption func(*Service) error

//添加chrome路徑信息,返回的是serviceOption類型
func ChromeDriver(path string) ServiceOption

//服務的結構體,包含隱藏類型
type Service struct {
    // contains filtered or unexported fields
}

//啓動chrome瀏覽器的服務器,返回service類型指針
func NewChromeDriverService(path string, port int, opts ...ServiceOption) (*Service, error)

//關閉服務,記得defer關閉
func (s *Service) Stop() error

// 第三類 chrome操作相關

//設置瀏覽器兼容性,map類型,比如chrome瀏覽器兼容性。
//caps := selenium.Capabilities{"browserName": "chrome"}
type Capabilities map[string]interface{}

//通過調用函數添加chrome兼容性
func (c Capabilities) AddChrome(f chrome.Capabilities)

//啓動webdriver實例
func NewRemote(capabilities Capabilities, urlPrefix string) (WebDriver, error)

//通過WebDriver接口可以看出具體頁面的實現的方法,是接口,接口裏面是實現的方法。
type WebDriver interface {
    //返回服務器環境的版本信息
    // Status returns various pieces of information about the server environment.
    Status() (*Status, error)

    //創建新的session
    // NewSession starts a new session and returns the session ID.
    NewSession() (string, error)

    //創建新的session(已廢棄)
    // SessionId returns the current session ID
    // Deprecated: This identifier is not Go-style correct. Use SessionID
    // instead.
    SessionId() string

    //獲取新的ssionid
    // SessionID returns the current session ID.
    SessionID() string

    //切換session
    // SwitchSession switches to the given session ID.
    SwitchSession(sessionID string) error

    //返回兼容性
    // Capabilities returns the current session's capabilities.
    Capabilities() (Capabilities, error)

    //設置異步腳本執行時間
    // SetAsyncScriptTimeout sets the amount of time that asynchronous scripts
    // are permitted to run before they are aborted. The timeout will be rounded
    // to nearest millisecond.
    SetAsyncScriptTimeout(timeout time.Duration) error

    //設置等待搜索元素的時間,目的: 如果頁面結果返回較慢,就需要等待頁面內容完整返回,然後再進行頁面元素操作。
    // SetImplicitWaitTimeout sets the amount of time the driver should wait when
    // searching for elements. The timeout will be rounded to nearest millisecond.
    SetImplicitWaitTimeout(timeout time.Duration) error

    //設置等待頁面的時間
    // SetPageLoadTimeout sets the amount of time the driver should wait when
    // loading a page. The timeout will be rounded to nearest millisecond.
    SetPageLoadTimeout(timeout time.Duration) error

    //設置會話退出
    // Quit ends the current session. The browser instance will be closed.
    Quit() error

    //獲取現在窗口句柄,一串序號,打開一個窗口一個句柄
    // CurrentWindowHandle returns the ID of current window handle.
    CurrentWindowHandle() (string, error)

    //獲取現在所有打開窗口句柄,獲取所有窗口句柄
    // WindowHandles returns the IDs of current open windows.
    WindowHandles() ([]string, error)

    //返回當前頁面連接的URL
    // CurrentURL returns the browser's current URL.
    CurrentURL() (string, error)

    //獲取當前頁面的標題
    // Title returns the current page's title.
    Title() (string, error)

    //返回當前頁面的所有內容
    // PageSource returns the current page's source.
    PageSource() (string, error)

    //關閉現在的窗口
    // Close closes the current window.
    Close() error

    //切換frame,frame裏面內嵌一個完整html,如果操作裏面的內容需要進入iframe中。switchframe(nil),返回到頂層
    // SwitchFrame switches to the given frame. The frame parameter can be the
    // frame's ID as a string, its WebElement instance as returned by
    // GetElement, or nil to switch to the current top-level browsing context.
    SwitchFrame(frame interface{}) error

    切換windows到指定窗口
    // SwitchWindow switches the context to the specified window.
    SwitchWindow(name string) error

    //關閉窗口
    // CloseWindow closes the specified window.
    CloseWindow(name string) error

    //設置最大化窗口
    // MaximizeWindow maximizes a window. If the name is empty, the current
    // window will be maximized.
    MaximizeWindow(name string) error

    //設置窗口尺寸
    // ResizeWindow changes the dimensions of a window. If the name is empty, the
    // current window will be maximized.
    ResizeWindow(name string, width, height int) error

    //通過url導航至相應界面。主要選項,就是打開url地址。
    // Get navigates the browser to the provided URL.
    Get(url string) error

    //向前翻
    // Forward moves forward in history.
    Forward() error

    //向後翻
    // Back moves backward in history.
    Back() error

    //刷新
    // Refresh refreshes the page.
    Refresh() error

    //查找定位一個html元素。
    // FindElement finds exactly one element in the current page's DOM.
    FindElement(by, value string) (WebElement, error)

    //查找定位多個的html元素
    // FindElement finds potentially many elements in the current page's DOM.
    FindElements(by, value string) ([]WebElement, error)

    //獲取當前焦點元素
    // ActiveElement returns the currently active element on the page.
    ActiveElement() (WebElement, error)

    //解碼元素響應
    // DecodeElement decodes a single element response.
    DecodeElement([]byte) (WebElement, error)

    //解碼多個元素響應
    // DecodeElements decodes a multi-element response.
    DecodeElements([]byte) ([]WebElement, error)

    //獲取所有cookie
    // GetCookies returns all of the cookies in the browser's jar.
    GetCookies() ([]Cookie, error)

    //獲取指定cookie
    // GetCookie returns the named cookie in the jar, if present. This method is
    // only implemented for Firefox.
    GetCookie(name string) (Cookie, error)

    //添加cookie到jar
    // AddCookie adds a cookie to the browser's jar.
    AddCookie(cookie *Cookie) error

    //刪除所有cookie
    // DeleteAllCookies deletes all of the cookies in the browser's jar.    
    DeleteAllCookies() error

    //刪除指定cookie
    // DeleteCookie deletes a cookie to the browser's jar.
    DeleteCookie(name string) error

    //敲擊鼠標按鈕
    // Click clicks a mouse button. The button should be one of RightButton,
    // MiddleButton or LeftButton.
    Click(button int) error

    //雙擊鼠標按鈕
    // DoubleClick clicks the left mouse button twice.
    DoubleClick() error

    //按下鼠標
    // ButtonDown causes the left mouse button to be held down.
    ButtonDown() error

    //擡起鼠標
    // ButtonUp causes the left mouse button to be released.
    ButtonUp() error

    //發送更改到活動元素(已丟棄)
    // SendModifier sends the modifier key to the active element. The modifier
    // can be one of ShiftKey, ControlKey, AltKey, MetaKey.
    //
    // Deprecated: Use KeyDown or KeyUp instead.
    SendModifier(modifier string, isDown bool) error

    //將按鍵順序序列發送到活動元素
    // KeyDown sends a sequence of keystrokes to the active element. This method
    // is similar to SendKeys but without the implicit termination. Modifiers are
    // not released at the end of each call.
    KeyDown(keys string) error

    //釋放發送的元素
    // KeyUp indicates that a previous keystroke sent by KeyDown should be
    // release
    KeyUp(keys string) error

    //拍攝快照
    // Screenshot takes a screenshot of the browser window.
    Screenshot() ([]byte, error)

    //日誌抓取
    // Log fetches the logs. Log types must be previously configured in the
    // capabilities.
    //
    // NOTE: will return an error (not implemented) on IE11 or Edge drivers.
    Log(typ log.Type) ([]log.Message, error)

    //解除警報
    // DismissAlert dismisses current alert.
    DismissAlert() error

    //接受警報
    // AcceptAlert accepts the current alert.
    AcceptAlert() error

    //返回現在警報內容
    // AlertText returns the current alert text.
    AlertText() (string, error)

    //發送警報內容
    // SetAlertText sets the current alert text.
    SetAlertText(text string) error

    //執行腳本
    // ExecuteScript executes a script.
    ExecuteScript(script string, args []interface{}) (interface{}, error)

    //異步執行腳本
    // ExecuteScriptAsync asynchronously executes a script.
    ExecuteScriptAsync(script string, args []interface{}) (interface{}, error)

    //執行源腳本
    // ExecuteScriptRaw executes a script but does not perform JSON decoding.
    ExecuteScriptRaw(script string, args []interface{}) ([]byte, error)

    //異步執行源腳本
    // ExecuteScriptAsyncRaw asynchronously executes a script but does not
    // perform JSON decoding.
    ExecuteScriptAsyncRaw(script string, args []interface{}) ([]byte, error)

    //等待條件爲真
    // WaitWithTimeoutAndInterval waits for the condition to evaluate to true.
    WaitWithTimeoutAndInterval(condition Condition, timeout, interval time.Duration) error

    //等待時間
    // WaitWithTimeout works like WaitWithTimeoutAndInterval, but with default polling interval.
    WaitWithTimeout(condition Condition, timeout time.Duration) error

    //等待
    //Wait works like WaitWithTimeoutAndInterval, but using the default timeout and polling interval.
    Wait(condition Condition) error
}

//對相關元素進行後續執行,接口類型,裏面是實現方法
type WebElement interface {
    // click選中的元素
    // Click clicks on the element.
    Click() error

    //發送數據到選中元素
    // SendKeys types into the element.
    SendKeys(keys string) error

    //提交按鈕
    // Submit submits the button.
    Submit() error

    //清空按鈕
    // Clear clears the element.
    Clear() error

    //移動元素到相應的座標
    // MoveTo moves the mouse to relative coordinates from center of element, If
    // the element is not visible, it will be scrolled into view.
    MoveTo(xOffset, yOffset int) error

    // 查找子元素
    // FindElement finds a child element.
    FindElement(by, value string) (WebElement, error)

    //查找多個子元素
    // FindElement finds multiple children elements.
    FindElements(by, value string) ([]WebElement, error)

    //返回標籤名稱
    // TagName returns the element's name.
    TagName() (string, error)

    //返回元素內容
    // Text returns the text of the element.
    Text() (string, error)

    //元素被選中返回真
    // IsSelected returns true if element is selected.
    IsSelected() (bool, error)

    //如果元素啓用返回真
    // IsEnabled returns true if the element is enabled.
    IsEnabled() (bool, error)

    //如果元素顯示返回真
    // IsDisplayed returns true if the element is displayed.
    IsDisplayed() (bool, error)
    //獲取元素的名稱
    // GetAttribute returns the named attribute of the element.
    GetAttribute(name string) (string, error)

    //範圍元素的位置
    // Location returns the element's location.
    Location() (*Point, error)

    //滾動後返回元素的位置
    // LocationInView returns the element's location once it has been scrolled
    // into view.
    LocationInView() (*Point, error)

    //返回元素的大小
    // Size returns the element's size.
    Size() (*Size, error)

    //返回css優先級
    // CSSProperty returns the value of the specified CSS property of the
    // element.
    CSSProperty(name string) (string, error)

    //返回屬性滾動的快照
    // Screenshot takes a screenshot of the attribute scroll'ing if necessary.
    Screenshot(scroll bool) ([]byte, error)
}
4.3 說明

5.基礎操作

​ 操作之前,先分享一個快速獲取CSS Selector和xpath的方法。

​ 大家用chrome瀏覽器訪問網頁,按F12後,點擊調試頁左上角Elements箭頭,然後鼠標移動到目的位置,即可顯示頁面對應的HTML 元素。

​ 右鍵選中的元素,選擇copy,此時可以根據直接選擇ID,CLASS,CSS Selector或Xpath的地址.

image.png

參考別人的案例,寫了幾個小案例,僅供參考。亮代碼吧。

  • 打開百度,自動搜索。

    package main
    
    import (
        "fmt"
        "github.com/tebeka/selenium"
        "time"
    )
    
    const (
        //設置常量 分別設置chromedriver.exe的地址和本地調用端口
        seleniumPath = `H:\webdriver\chromedriver.exe`
        port         = 9515
    )
    
    func main() {
        //1.開啓selenium服務
        //設置selium服務的選項,設置爲空。根據需要設置。
        ops := []selenium.ServiceOption{}
        service, err := selenium.NewChromeDriverService(seleniumPath, port, ops...)
        if err != nil {
            fmt.Printf("Error starting the ChromeDriver server: %v", err)
        }
        //延遲關閉服務
        defer service.Stop()
    
        //2.調用瀏覽器
        //設置瀏覽器兼容性,我們設置瀏覽器名稱爲chrome
        caps := selenium.Capabilities{
            "browserName": "chrome",
        }
        //調用瀏覽器urlPrefix: 測試參考:DefaultURLPrefix = "http://127.0.0.1:4444/wd/hub"
        wd, err := selenium.NewRemote(caps, "http://127.0.0.1:9515/wd/hub")
        if err != nil {
            panic(err)
        }
        //延遲退出chrome
        defer wd.Quit()
    
        //3.對頁面元素進行操作
        //獲取百度頁面
        if err := wd.Get("https://www.baidu.com/"); err != nil {
            panic(err)
        }
        //找到百度輸入框id
        we, err := wd.FindElement(selenium.ByID, "kw")
        if err != nil {
            panic(err)
        }
        //向輸入框發送“”
        err = we.SendKeys("天下第一")
        if err != nil {
            panic(err)
        }
    
        //找到百度提交按鈕id
        we, err = wd.FindElement(selenium.ByID, "su")
        if err != nil {
            panic(err)
        }
        //點擊提交
        err = we.Click()
        if err != nil {
            panic(err)
        }
    
        //睡眠20秒後退出
        time.Sleep(20 * time.Second)
    }
  • 內嵌iframe切換。

    package main
    
    import (
        "fmt"
        "github.com/tebeka/selenium"
        "time"
    )
    
    const (
        //設置常量 分別設置chromedriver.exe的地址和本地調用端口
        seleniumPath = `H:\webdriver\chromedriver.exe`
        port         = 9515
    )
    
    func main() {
        //1.開啓selenium服務
        //設置selium服務的選項,設置爲空。根據需要設置。
        ops := []selenium.ServiceOption{}
        service, err := selenium.NewChromeDriverService(seleniumPath, port, ops...)
        if err != nil {
            fmt.Printf("Error starting the ChromeDriver server: %v", err)
        }
        //延遲關閉服務
        defer service.Stop()
    
        //2.調用瀏覽器
        //設置瀏覽器兼容性,我們設置瀏覽器名稱爲chrome
        caps := selenium.Capabilities{
            "browserName": "chrome",
        }
        //調用瀏覽器urlPrefix: 測試參考:DefaultURLPrefix = "http://127.0.0.1:4444/wd/hub"
        wd, err := selenium.NewRemote(caps, "http://127.0.0.1:9515/wd/hub")
        if err != nil {
            panic(err)
        }
        //延遲退出chrome
        defer wd.Quit()
    
        //3.對頁面元素進行操作
        //獲取測試網頁
        if err := wd.Get("http://cdn1.python3.vip/files/selenium/sample2.html"); err != nil {
            panic(err)
        }
    
        //4.切換到相應的frame上去
        //wd.SwitchFrame(可以id或者frame獲取的webelement),我們使用二種方式分別實現。
    
        //4.1 通過frame的id查找 此時id=frame1
        /*
            err = wd.SwitchFrame("frame1")
            if err != nil {
                panic(err)
            }
    
            // 此時定位到iframe的html中,再像使用bycssselector即可
            // 因爲animal包含多個對象,我們使用findelements
            wes, err := wd.FindElements(selenium.ByCSSSelector, ".animal")
            if err != nil {
                panic(err)
            }
    
            //循環獲取每個元素的信息
            for _,we := range  wes {
                text, err := we.Text()
    
                if err != nil {
                    panic(err)
                }
                fmt.Println(text)
            }
        */
    
        //4.2 frame獲取的webelement,通過切換webelement實現。
        // 找到ifname的webelement對象
        element, err := wd.FindElement(selenium.ByCSSSelector, "#frame1")
        // 不同的獲取element方式
        //element, err := wd.FindElement(selenium.ByCSSSelector, `iframe[name="innerFrame"]`)
        if err != nil {
            panic(err)
        }
        //切換到iframe中
        err = wd.SwitchFrame(element)
        if err != nil {
            panic(err)
        }
    
        // 此時定位到iframe的html中,再像使用bycssselector即可
        // 因爲animal包含多個對象,我們使用findelements
        wes, err := wd.FindElements(selenium.ByCSSSelector, ".animal")
        if err != nil {
            panic(err)
        }
    
        //循環獲取每個元素的信息
        for _, we := range wes {
            text, err := we.Text()
            if err != nil {
                panic(err)
            }
            fmt.Println(text)
        }
    
        //5.切換回頂層frame,因爲切換中frame中是不能操作外層值元素的,所以我們要切換出來
        //frame=nil是切換回頂層frame
        err = wd.SwitchFrame(nil)
        if err != nil {
            panic(err)
        }
        //根據class name選擇元素
        we, err := wd.FindElement(selenium.ByCSSSelector, ".baiyueheiyu")
        if err != nil {
            panic(err)
        }
        //查看頂層元素的內容
        fmt.Println(we.Text())
    
        //睡眠20秒後退出
        time.Sleep(20 * time.Second)
    }
  • 多windows切換。

    package main
    
    import (
        "fmt"
        "github.com/tebeka/selenium"
        "strings"
        "time"
    )
    
    const (
        //設置常量 分別設置chromedriver.exe的地址和本地調用端口
        seleniumPath = `H:\webdriver\chromedriver.exe`
        port         = 9515
    )
    
    func main() {
        //1.開啓selenium服務
        //設置selenium服務的選項,設置爲空。根據需要設置。
        ops := []selenium.ServiceOption{}
        service, err := selenium.NewChromeDriverService(seleniumPath, port, ops...)
        if err != nil {
            fmt.Printf("Error starting the ChromeDriver server: %v", err)
        }
        //延遲關閉服務
        defer service.Stop()
    
        //2.調用瀏覽器實例
        //設置瀏覽器兼容性,我們設置瀏覽器名稱爲chrome
        caps := selenium.Capabilities{
            "browserName": "chrome",
        }
        //調用瀏覽器urlPrefix: 測試參考:DefaultURLPrefix = "http://127.0.0.1:4444/wd/hub"
        wd, err := selenium.NewRemote(caps, "http://127.0.0.1:9515/wd/hub")
        if err != nil {
            panic(err)
        }
        //延遲退出chrome
        defer wd.Quit()
    
        //3.打開多頁面chrome實例
        //目前就想到兩種方式可以打開,
        //第一種就是頁面中有url連接,通過click()方式打開
        //第二種方式就是通過腳本方式打開。wd.ExecuteScript
        if err := wd.Get("http://cdn1.python3.vip/files/selenium/sample3.html"); err != nil {
            panic(err)
        }
    
        //第一種方式,找到頁面中的url地址,進行頁面跳轉
        we, err := wd.FindElement(selenium.ByTagName, "a")
        if err != nil {
            panic(err)
        }
        we.Click()
    
        //第二種方式,通過運行通用的js腳本打開新窗口,因爲我們暫時不需要操作獲取的結果,所有不獲取返回值。
        wd.ExecuteScript(`window.open("https://www.qq.com", "_blank");`, nil)
        wd.ExecuteScript(`window.open("https://www.runoob.com/jsref/obj-window.html", "_blank");`, nil)
    
        //這一行是發送警報信息,寫這一行的目的,主要是看當前主窗口是哪一個
        wd.ExecuteScript(`window.alert(location.href);`, nil)
    
        //查看當前窗口的handle值
        handle, err := wd.CurrentWindowHandle()
        if err != nil {
            panic(err)
        }
        fmt.Println(handle)
        fmt.Println("--------------------------")
    
        //查看所有網頁的handle值
        handles, err := wd.WindowHandles()
        if err != nil {
            panic(err)
        }
        for _, handle := range handles {
            fmt.Println(handle)
        }
        fmt.Println("--------------------------")
    
        //4.跳轉到指定的網頁
        //我們雖然打開了多個頁面,但是我們當前的handle值,還是第一個頁面的,我們要想辦法搞定它。
        //記得保存當前主頁面的handle值
        //mainhandle := handle
    
        //通過判斷條件進行相應的網頁
        //獲取所有handle值
        handles, err = wd.WindowHandles()
        if err != nil {
            panic(err)
        }
    
        //遍歷所有handle值,通過url找到目標頁面,判斷相等時,break出來,就是停到相應的頁面了。
        for _, handle := range handles {
            wd.SwitchWindow(handle)
            url, _ := wd.CurrentURL()
            if strings.Contains(url, "qq.com") {
                break
            }
        }
        //查看此頁面的handle
        handle, err = wd.CurrentWindowHandle()
        if err != nil {
            panic(err)
        }
        fmt.Println(handle)
        //這一行是發送警報信息,寫這一行的目的,主要是看當前主窗口是哪一個
        wd.ExecuteScript(`window.alert(location.href);`, nil)
    
        //切換回第一個頁面
        //wd.SwitchWindow(mainhandle)
    
        //睡眠20秒後退出
        time.Sleep(20 * time.Second)
    }
  • 單選,多選框操作。

    package main
    
    import (
        "fmt"
        "github.com/tebeka/selenium"
        "time"
    )
    
    const (
        //設置常量 分別設置chromedriver.exe的地址和本地調用端口
        seleniumPath = `H:\webdriver\chromedriver.exe`
        port         = 9515
    )
    
    func main() {
        //1.開啓selenium服務
        //設置selenium服務的選項,設置爲空。根據需要設置。
        ops := []selenium.ServiceOption{}
        service, err := selenium.NewChromeDriverService(seleniumPath, port, ops...)
        if err != nil {
            fmt.Printf("Error starting the ChromeDriver server: %v", err)
        }
        //延遲關閉服務
        defer service.Stop()
    
        //2.調用瀏覽器實例
        //設置瀏覽器兼容性,我們設置瀏覽器名稱爲chrome
        caps := selenium.Capabilities{
            "browserName": "chrome",
        }
        //調用瀏覽器urlPrefix: 測試參考:DefaultURLPrefix = "http://127.0.0.1:4444/wd/hub"
        wd, err := selenium.NewRemote(caps, "http://127.0.0.1:9515/wd/hub")
        if err != nil {
            panic(err)
        }
        //延遲退出chrome
        defer wd.Quit()
    
        // 3單選radio,多選checkbox,select框操作(功能待完善,https://github.com/tebeka/selenium/issues/141)
        if err := wd.Get("http://cdn1.python3.vip/files/selenium/test2.html"); err != nil {
            panic(err)
        }
        //3.1操作單選radio
        we, err := wd.FindElement(selenium.ByCSSSelector, `#s_radio > input[type=radio]:nth-child(3)`)
        if err != nil {
            panic(err)
        }
        we.Click()
    
        //3.2操作多選checkbox
        //刪除默認checkbox
        we, err = wd.FindElement(selenium.ByCSSSelector, `#s_checkbox > input[type=checkbox]:nth-child(5)`)
        if err != nil {
            panic(err)
        }
        we.Click()
        //選擇選項
        we, err = wd.FindElement(selenium.ByCSSSelector, `#s_checkbox > input[type=checkbox]:nth-child(1)`)
        if err != nil {
            panic(err)
        }
        we.Click()
        we, err = wd.FindElement(selenium.ByCSSSelector, `#s_checkbox > input[type=checkbox]:nth-child(3)`)
        if err != nil {
            panic(err)
        }
        we.Click()
    
        //3.3 select多選
        //刪除默認選項
    
        //選擇默認項
        we, err = wd.FindElement(selenium.ByCSSSelector, `#ss_multi > option:nth-child(3)`)
        if err != nil {
            panic(err)
        }
        we.Click()
    
        we, err = wd.FindElement(selenium.ByCSSSelector, `#ss_multi > option:nth-child(2)`)
        if err != nil {
            panic(err)
        }
        we.Click()
    
        //睡眠20秒後退出
        time.Sleep(20 * time.Second)
    }
    

結束語

​ 個人理解,僅供參考。如有錯誤,歡迎指正。

​ 一直在路上,默默前行。

參考

selenium的golang代碼包

selenium-golangdoc

自動化測試

golang driver使用記錄

windows對象

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章