您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“go語言怎么使用Chromedp實現二維碼登陸”,內容詳細,步驟清晰,細節處理妥當,希望這篇“go語言怎么使用Chromedp實現二維碼登陸”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
chromedp是一個更快、更簡單的Golang庫用于調用支持Chrome DevTools協議的瀏覽器,同時不需要額外的依賴(例如Selenium和PhantomJS)
Chrome和Golang都與Google有著相當密切的關系,而Chrome DevTools其實就是Chrome瀏覽器按下F12之后的控制終端
對于Golang開發來說,使用chromedp更為便捷,因為它僅僅需要Chrome瀏覽器而并不需要依賴ChromeDriver,省去了依賴問題,有助于自動化的構建和多平臺架構的遷移
如何使用chromedp進行二維碼登陸
如何將二維碼展示在無圖形化的終端上(makiuchi-d/gozxing解碼 skip2/ go-qrcode編碼)
如何保存Cookies實現短時間免登陸
網站會更新,文章不保證更新,請務必學會舉一反三
下載并安裝Chrome瀏覽器
創建Golang項目,開啟Go Module(在項目目錄下使用終端輸入go mod init)
在項目目錄下使用終端輸入:
go get -u github.com/chromedp/chromedp
(如果有依賴問題請刪除-u)
(以金山文檔https://account.wps.cn/為例)
1.重新設置chromedp使用"有頭"的方式打開,以便于我們進行debug
func main(){ // chromdp依賴context上限傳遞參數 ctx, _ := chromedp.NewExecAllocator( context.Background(), // 以默認配置的數組為基礎,覆寫headless參數 // 當然也可以根據自己的需要進行修改,這個flag是瀏覽器的設置 append( chromedp.DefaultExecAllocatorOptions[:], chromedp.Flag("headless", false), )..., ) }
2.創建chromedp上下文對象
func main(){ // chromdp依賴context上限傳遞參數 ... // 創建新的chromedp上下文對象,超時時間的設置不分先后 // 注意第二個返回的參數是cancel(),只是我省略了 ctx, _ = context.WithTimeout(ctx, 30*time.Second) ctx, _ = chromedp.NewContext( ctx, // 設置日志方法 chromedp.WithLogf(log.Printf), ) // 通常可以使用 defer cancel() 去取消 // 但是在Windows環境下,我們希望程序能順帶關閉掉瀏覽器 // 如果不希望瀏覽器關閉,使用cancel()方法即可 // defer cancel() // defer chromedp.Cancel(ctx) }
3.執行自定義的任務
func main(){ // chromdp依賴context上限傳遞參數 ... // 創建新的chromedp上下文對象,超時時間的設置不分先后 // 注意第二個返回的參數是cancel(),只是我省略了 ... // 執行我們自定義的任務 - myTasks函數在第4步 if err := chromedp.Run(ctx, myTasks()); err != nil { log.Fatal(err) return } }
4.至此程序的初始化過程已經完成,接下來就是任務——打開登陸頁面
// 自定義任務 func myTasks() chromedp.Tasks { return chromedp.Tasks{ // 1. 打開金山文檔的登陸界面 chromedp.Navigate(loginURL), } }
5.運行一下程序,可以看到Chrome被打開,同時訪問了我們指定的網站
1.需要點擊微信登陸按鈕,先找到按鈕的選擇器,右鍵按鈕并在菜單中點擊檢查,然后可以看到按鈕的元素
2.右鍵元素打開菜單找到copy下的copy selector,即獲取到選擇器
3.我們嘗試點擊微信登陸按鈕,發現還需要點擊一下確認,重復上述步驟獲取確認按鈕的選擇器
4.用代碼執行上述點擊步驟
// 自定義任務 func myTasks() chromedp.Tasks { return chromedp.Tasks{ // 1. 打開金山文檔的登陸界面 chromedp.Navigate(loginURL), // 2. 點擊微信登陸按鈕 // #wechat > span:nth-child(2) chromedp.Click(`#wechat > span:nth-child(2)`), // 3. 點擊確認按鈕 // #dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok chromedp.Click(`#dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok`), } }
5.運行程序即可直達二維碼展示界面
6.用同樣的方式,獲取二維碼圖片的選擇器
7.用代碼實現獲取二維碼
有兩點需要注意,第一是二維碼有加載過程,第二是二維碼是元素渲染,
我們需要用截圖的方式獲取(也可以用js來獲取對應的href并下載,但是為了照顧小白,選擇最簡單的)
func myTasks() chromedp.Tasks { return chromedp.Tasks{ // 1. 打開金山文檔的登陸界面 ... // 2. 點擊微信登陸按鈕 ... // 3. 點擊確認按鈕 ... // 4. 獲取二維碼 // #wximport getCode(), } } func getCode() chromedp.ActionFunc { return func(ctx context.Context) (err error) { // 1. 用于存儲圖片的字節切片 var code []byte // 2. 截圖 // 注意這里需要注明直接使用ID選擇器來獲取元素(chromedp.ByID) if err = chromedp.Screenshot(`#wximport`, &code, chromedp.ByID).Do(ctx); err != nil { return } // 3. 保存文件 if err = ioutil.WriteFile("code.png", code, 0755); err != nil { return } return } }
8.執行程序即可發現目錄下已經存儲了二維碼圖片文件,我們可以通過掃描此二維碼進行登陸,與瀏覽器上掃描為同一種效果
(與chromedp無關,屬于額外內容)
1.在上述步驟中,我們已經獲取了二維碼,接下來我們需要在終端顯示二維碼,首先是解碼,這里使用gozxing庫
func printQRCode(code []byte) (err error) { // 1. 因為我們的字節流是圖像,所以我們需要先解碼字節流 img, _, err := image.Decode(bytes.NewReader(code)) if err != nil { return } // 2. 然后使用gozxing庫解碼圖片獲取二進制位圖 bmp, err := gozxing.NewBinaryBitmapFromImage(img) if err != nil { return } // 3. 用二進制位圖解碼獲取gozxing的二維碼對象 res, err := qrcode.NewQRCodeReader().Decode(bmp, nil) if err != nil { return } return }
2.然后重新編碼來輸出二維碼到終端,這里使用go-qrcode庫
// 請注意import的庫發生了重名 import ( "github.com/makiuchi-d/gozxing" "github.com/makiuchi-d/gozxing/qrcode" goQrcode "github.com/skip2/go-qrcode" ) func printQRCode(code []byte) (err error) { // 1. 因為我們的字節流是圖像,所以我們需要先解碼字節流 ... // 2. 然后使用gozxing庫解碼圖片獲取二進制位圖 ... // 3. 用二進制位圖解碼獲取gozxing的二維碼對象 ... // 4. 用結果來獲取go-qrcode對象(注意這里我用了庫的別名) qr, err := goQrcode.New(res.String(), goQrcode.High) if err != nil { return } // 5. 輸出到標準輸出流 fmt.Println(qr.ToSmallString(false)) return }
3.修改我們第二步的過程
func getCode() chromedp.ActionFunc { return func(ctx context.Context) (err error) { // 1. 用于存儲圖片的字節切片 ... // 2. 截圖 // 注意這里需要注明直接使用ID選擇器來獲取元素(chromedp.ByID) ... // 3. 把二維碼輸出到標準輸出流 if err = printQRCode(code); err != nil { return err } return } }
3.運行程序即可查看效果
1.在上述過程中,我們可以通過二維碼掃描登陸,網站會在登陸之后進行跳轉,跳轉后我們需要保存cookies來維持我們的登錄狀態,代碼實現如下
// 保存Cookies func saveCookies() chromedp.ActionFunc { return func(ctx context.Context) (err error) { // 等待二維碼登陸 if err = chromedp.WaitVisible(`#app`, chromedp.ByID).Do(ctx); err != nil { return } // cookies的獲取對應是在devTools的network面板中 // 1. 獲取cookies cookies, err := network.GetAllCookies().Do(ctx) if err != nil { return } // 2. 序列化 cookiesData, err := network.GetAllCookiesReturns{Cookies: cookies}.MarshalJSON() if err != nil { return } // 3. 存儲到臨時文件 if err = ioutil.WriteFile("cookies.tmp", cookiesData, 0755); err != nil { return } return } }
2.獲取到Cookies之后,我們需要在程序運行時將Cookies從臨時文件中加載到瀏覽器中
// 加載Cookies func loadCookies() chromedp.ActionFunc { return func(ctx context.Context) (err error) { // 如果cookies臨時文件不存在則直接跳過 if _, _err := os.Stat("cookies.tmp"); os.IsNotExist(_err) { return } // 如果存在則讀取cookies的數據 cookiesData, err := ioutil.ReadFile("cookies.tmp") if err != nil { return } // 反序列化 cookiesParams := network.SetCookiesParams{} if err = cookiesParams.UnmarshalJSON(cookiesData); err != nil { return } // 設置cookies return network.SetCookies(cookiesParams.Cookies).Do(ctx) } }
3.通過上述兩步我們已經可以保持登陸狀態,然后我們需要檢查一下是否成功,這里調用瀏覽器執行js腳本獲取當前頁面的網址,判斷是否已經個人中心頁面,如果為真,則停止操作
// 檢查是否登陸 func checkLoginStatus() chromedp.ActionFunc { return func(ctx context.Context) (err error) { var url string if err = chromedp.Evaluate(`window.location.href`, &url).Do(ctx); err != nil { return } if strings.Contains(url, "https://account.wps.cn/usercenter/apps") { log.Println("已經使用cookies登陸") chromedp.Stop() } return } }
4.最終重新設置我們的瀏覽器任務即可
// 自定義任務 func myTasks() chromedp.Tasks { return chromedp.Tasks{ // 0. 加載cookies <-- 變動 loadCookies(), // 1. 打開金山文檔的登陸界面 ... // 判斷一下是否已經登陸 <-- 變動 checkLoginStatus(), // 2. 點擊微信登陸按鈕 // #wechat > span:nth-child(2) ... // 3. 點擊確認按鈕 // #dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok ... // 4. 獲取二維碼 // #wximport ... // 5. 若二維碼登錄后,瀏覽器會自動跳轉到用戶信息頁面 <-- 變動 saveCookies(), } }
5.我們使用已經登陸的cookies運行程序可以發現我們成功跳過登陸過程
讀到這里,這篇“go語言怎么使用Chromedp實現二維碼登陸”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。