生活随笔
收集整理的這篇文章主要介紹了
Golang爬虫终极杀器——Chromedp让你成为二维码登陆终结者(教程)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Golang爬蟲終極殺器——Chromedp讓你成為二維碼登陸終結(jié)者(教程)
Github源碼 - chromedp文章項(xiàng)目Gitee源碼
1 Chromedp是什么
chromedp是一個(gè)更快、更簡(jiǎn)單的Golang庫用于調(diào)用支持Chrome DevTools協(xié)議的瀏覽器,同時(shí)不需要額外的依賴(例如Selenium和PhantomJS)
Chrome和Golang都與Google有著相當(dāng)密切的關(guān)系,而Chrome DevTools其實(shí)就是Chrome瀏覽器按下F12之后的控制終端
2 為什么不使用Selenium
對(duì)于Golang開發(fā)來說,使用chromedp更為便捷,因?yàn)樗鼉H僅需要Chrome瀏覽器而并不需要依賴ChromeDriver,省去了依賴問題,有助于自動(dòng)化的構(gòu)建和多平臺(tái)架構(gòu)的遷移
3 文章解決了什么需求
如何使用chromedp進(jìn)行二維碼登陸如何將二維碼展示在無圖形化的終端上(makiuchi-d/gozxing解碼 skip2/ go-qrcode編碼)如何保存Cookies實(shí)現(xiàn)短時(shí)間免登陸
網(wǎng)站會(huì)更新,文章不保證更新,請(qǐng)務(wù)必學(xué)會(huì)舉一反三
4 如何使用chromedp進(jìn)行二維碼登陸
4.1 安裝chromedp
下載并安裝Chrome瀏覽器創(chuàng)建Golang項(xiàng)目,開啟Go Module(在項(xiàng)目目錄下使用終端輸入go mod init)在項(xiàng)目目錄下使用終端輸入:go get -u github.com/chromedp/chromedp(如果有依賴問題請(qǐng)刪除-u)
4.2 嘗試打開網(wǎng)站(以金山文檔https://account.wps.cn/為例)
重新設(shè)置chromedp使用"有頭"的方式打開,以便于我們進(jìn)行debug
func main(){ctx
, _ := chromedp
.NewExecAllocator(context
.Background(),append(chromedp
.DefaultExecAllocatorOptions
[:],chromedp
.Flag("headless", false),)...,)
}
創(chuàng)建chromedp上下文對(duì)象
func main(){...ctx
, _ = context
.WithTimeout(ctx
, 30*time
.Second
)ctx
, _ = chromedp
.NewContext(ctx
,chromedp
.WithLogf(log
.Printf
),)
}
執(zhí)行自定義的任務(wù)
func main(){......if err
:= chromedp
.Run(ctx
, myTasks()); err
!= nil {log
.Fatal(err
)return}
}
至此程序的初始化過程已經(jīng)完成,接下來就是任務(wù)——打開登陸頁面
func myTasks() chromedp
.Tasks
{return chromedp
.Tasks
{chromedp
.Navigate(loginURL
),}
}
運(yùn)行一下程序,可以看到Chrome被打開,同時(shí)訪問了我們指定的網(wǎng)站
4.3 獲取二維碼(點(diǎn)擊過程)
需要點(diǎn)擊微信登陸按鈕,先找到按鈕的選擇器,右鍵按鈕并在菜單中點(diǎn)擊檢查,然后可以看到按鈕的元素
右鍵元素打開菜單找到copy下的copy selector,即獲取到選擇器
我們嘗試點(diǎn)擊微信登陸按鈕,發(fā)現(xiàn)還需要點(diǎn)擊一下確認(rèn),重復(fù)上述步驟獲取確認(rèn)按鈕的選擇器
用代碼執(zhí)行上述點(diǎn)擊步驟
func myTasks() chromedp
.Tasks
{return chromedp
.Tasks
{chromedp
.Navigate(loginURL
),chromedp
.Click(`#wechat > span:nth-child(2)`),chromedp
.Click(`#dialog > div.dialog-wrapper > div > div.dialog-footer > div.dialog-footer-ok`),}
}
運(yùn)行程序即可直達(dá)二維碼展示界面
用同樣的方式,獲取二維碼圖片的選擇器
用代碼實(shí)現(xiàn)獲取二維碼,有兩點(diǎn)需要注意,第一是二維碼有加載過程,第二是二維碼是元素渲染,我們需要用截圖的方式獲取(也可以用js來獲取對(duì)應(yīng)的href并下載,但是為了照顧小白,選擇最簡(jiǎn)單的)
func myTasks() chromedp
.Tasks
{return chromedp
.Tasks
{.........getCode(),}
}func getCode() chromedp
.ActionFunc
{return func(ctx context
.Context
) (err
error) {var code
[]byteif err
= chromedp
.Screenshot(`#wximport`, &code
, chromedp
.ByID
).Do(ctx
); err
!= nil {return}if err
= ioutil
.WriteFile("code.png", code
, 0755); err
!= nil {return}return}
}
執(zhí)行程序即可發(fā)現(xiàn)目錄下已經(jīng)存儲(chǔ)了二維碼圖片文件,我們可以通過掃描此二維碼進(jìn)行登陸,與瀏覽器上掃描為同一種效果
5. 如何將二維碼展示在無圖形化的終端上(與chromedp無關(guān),屬于額外內(nèi)容)
在上述步驟中,我們已經(jīng)獲取了二維碼,接下來我們需要在終端顯示二維碼,首先是解碼,這里使用gozxing庫
func printQRCode(code
[]byte) (err
error) {img
, _, err
:= image
.Decode(bytes
.NewReader(code
))if err
!= nil {return}bmp
, err
:= gozxing
.NewBinaryBitmapFromImage(img
)if err
!= nil {return}res
, err
:= qrcode
.NewQRCodeReader().Decode(bmp
, nil)if err
!= nil {return}return
}
然后重新編碼來輸出二維碼到終端,這里使用go-qrcode庫
import ("github.com/makiuchi-d/gozxing""github.com/makiuchi-d/gozxing/qrcode"goQrcode
"github.com/skip2/go-qrcode"
)func printQRCode(code
[]byte) (err
error) {.........qr
, err
:= goQrcode
.New(res
.String(), goQrcode
.High
)if err
!= nil {return}fmt
.Println(qr
.ToSmallString(false))return
}
修改我們第二步的過程
func getCode() chromedp
.ActionFunc
{return func(ctx context
.Context
) (err
error) {......if err
= printQRCode(code
); err
!= nil {return err
}return}
}
運(yùn)行程序即可查看效果
6. 如何保存Cookies實(shí)現(xiàn)短時(shí)間免登陸
在上述過程中,我們可以通過二維碼掃描登陸,網(wǎng)站會(huì)在登陸之后進(jìn)行跳轉(zhuǎn),跳轉(zhuǎn)后我們需要保存cookies來維持我們的登錄狀態(tài),代碼實(shí)現(xiàn)如下
func saveCookies() chromedp
.ActionFunc
{return func(ctx context
.Context
) (err
error) {if err
= chromedp
.WaitVisible(`#app`, chromedp
.ByID
).Do(ctx
); err
!= nil {return}cookies
, err
:= network
.GetAllCookies().Do(ctx
)if err
!= nil {return}cookiesData
, err
:= network
.GetAllCookiesReturns
{Cookies
: cookies
}.MarshalJSON()if err
!= nil {return}if err
= ioutil
.WriteFile("cookies.tmp", cookiesData
, 0755); err
!= nil {return}return}
}
獲取到Cookies之后,我們需要在程序運(yùn)行時(shí)將Cookies從臨時(shí)文件中加載到瀏覽器中
func loadCookies() chromedp
.ActionFunc
{return func(ctx context
.Context
) (err
error) {if _, _err
:= os
.Stat("cookies.tmp"); os
.IsNotExist(_err
) {return}cookiesData
, err
:= ioutil
.ReadFile("cookies.tmp")if err
!= nil {return}cookiesParams
:= network
.SetCookiesParams
{}if err
= cookiesParams
.UnmarshalJSON(cookiesData
); err
!= nil {return}return network
.SetCookies(cookiesParams
.Cookies
).Do(ctx
)}
}
通過上述兩步我們已經(jīng)可以保持登陸狀態(tài),然后我們需要檢查一下是否成功,這里調(diào)用瀏覽器執(zhí)行js腳本獲取當(dāng)前頁面的網(wǎng)址,判斷是否已經(jīng)個(gè)人中心頁面,如果為真,則停止操作
func checkLoginStatus() chromedp
.ActionFunc
{return func(ctx context
.Context
) (err
error) {var url
stringif err
= chromedp
.Evaluate(`window.location.href`, &url
).Do(ctx
); err
!= nil {return}if strings
.Contains(url
, "https://account.wps.cn/usercenter/apps") {log
.Println("已經(jīng)使用cookies登陸")chromedp
.Stop()}return}
}
最終重新設(shè)置我們的瀏覽器任務(wù)即可
func myTasks() chromedp
.Tasks
{return chromedp
.Tasks
{loadCookies(),...checkLoginStatus(),.........saveCookies(),}
}
我們使用已經(jīng)登陸的cookies運(yùn)行程序可以發(fā)現(xiàn)我們成功跳過登陸過程
總結(jié)
以上是生活随笔為你收集整理的Golang爬虫终极杀器——Chromedp让你成为二维码登陆终结者(教程)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。