# Day25 Golang 爬蟲框架 colly 模擬使用者登入 今天來繼續做比昨天更具 沒意義的事。 我想透過爬蟲設定帳號密碼,來自動登入 [**iT邦幫忙**](https://member.ithome.com.tw/login) 這個優質論壇。 ## 模擬使用者登入 首先要觀察敵情,登入自己的帳號密碼來看看整個流程  按下登入按鈕。 熟練按下鍵盤上的`F12`,打開**開發者工具**,熟門熟路將欄位切換到`Network`, 仔細尋找登入的頁面在哪裡。一邊尋找一邊往下拉,  (可以透過設定 Setting Preserve Log來保留日誌,就算跳頁、刷新也不會消失)   诶?有個叫作`login`的看起來很可疑,畢竟中文意思就是**登入**嘛~! 點開`login`頁面之後往裡頭猛一瞧, 天哪!!  剛剛所輸入的帳號密碼就在眼前! 沒錯,**就是他了**,警察叔叔!這裡有人密碼露出來了! 回頭看看 **登入頁面** 的原始碼中的 **登入表單**, 彼此參照對應一下:`_token"`、`account`、`password` 然後`method="POST"` ```html <form method="POST" action="..."><input name="_token" type="hidden" value="..."> <input type="hidden" name="_token" value="......"> <div class="form-group ..."> <label class="sr-only">帳號</label> <input id="account" placeholder="帳號(非email)" name="account"> <i class="..."></i> </div> <div class="..."> <label class="sr-only">密碼</label> <input id="password" placeholder="密碼" name="password" value=""> <i class="..."></i> </div> ``` --- 也就是說,登入時需要的參數有三個:`帳號、密碼、_Token` ## Token 代幣 上英文課舉手發問、或者回答問題時,英文老師都給個塑膠Token、或乖寶寶貼紙, 有了這枚Token下課就可以跟老師要分數,就是這個Token。 `Token`常被拿來當作`訪問令牌 (Access token)`或是`會話連線 (Session ID)`,通常具有時效性。可以拿來做 使用者重複登入時做後踢前、或者使用者閒置多久做登出的動作。 在**iT邦幫忙**中,登入前會給個Token,在登入的時候代入、驗證Token,代表這一次的連線訪問(Session)。 所以必須先取得這個Token。 ```go package main import ( "fmt" "github.com/gocolly/colly/v2" ) var token string func main() { var url = "https://member.ithome.com.tw/login" c := colly.NewCollector() // 拿到這次登入的Token c.OnHTML("input[name='_token']", func(e *colly.HTMLElement) { token = e.Attr("value") }) c.OnScraped(func(r *colly.Response) { fmt.Println(string(r.Body)) }) c.Visit(url) fmt.Println(token) } ``` 輕輕鬆鬆拿到代幣了。 --- ## 帳號密碼 再來要考慮的是,如何在一個Session裡做登入(畢竟下一次訪問網站,勢必會換個連線Session,Token肯定不會是剛剛那個。) 用同一個`colly Collector`來做POST Payload,傳帳號密碼進去。 ```go package main import ( "fmt" "github.com/gocolly/colly/v2" "log" ) var token string func main() { var url = "https://member.ithome.com.tw/login" c := colly.NewCollector() // 拿到這次登入的Token c.OnHTML("input[name='_token']", func(e *colly.HTMLElement) { token = e.Attr("value") }) c.Visit(url) c.OnRequest(func(r *colly.Request) { r.Headers.Set("User-Agent", "Chrome/84.0.4147.89 Safari/537.36") r.Headers.Set("Host", "https://member.ithome.com.tw") r.Headers.Set("Origin", "https://member.ithome.com.tw") r.Headers.Set("Referer", "https://member.ithome.com.tw/login") // 這幾行在這iT邦幫忙沒有起到作用,但有些網站會照這些資訊判斷、阻擋其他來源 }) c.OnScraped(func(r *colly.Response) { fmt.Println(string(r.Body)) }) var formData = map[string]string{ "account": "你的名字", "password": "你的30公分", "_token": token, } err := c.Post(url, formData) // 進到該url 執行POST if err != nil { log.Println(err) } } ``` 可以在返回的html原始碼中,找到自己的`姓名`、`帳號`,那就是成功登入哩。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up