今天來繼續做比昨天更具 沒意義的事。
我想透過爬蟲設定帳號密碼,來自動登入 iT邦幫忙 這個優質論壇。
首先要觀察敵情,登入自己的帳號密碼來看看整個流程
按下登入按鈕。
熟練按下鍵盤上的F12
,打開開發者工具,熟門熟路將欄位切換到Network
,
仔細尋找登入的頁面在哪裡。一邊尋找一邊往下拉,
(可以透過設定 Setting Preserve Log來保留日誌,就算跳頁、刷新也不會消失)
诶?有個叫作login
的看起來很可疑,畢竟中文意思就是登入嘛~!
點開login
頁面之後往裡頭猛一瞧,
天哪!!
剛剛所輸入的帳號密碼就在眼前!
沒錯,就是他了,警察叔叔!這裡有人密碼露出來了!
回頭看看 登入頁面 的原始碼中的 登入表單,
彼此參照對應一下:_token"
、account
、password
然後method="POST"
<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
常被拿來當作訪問令牌 (Access token)
或是會話連線 (Session ID)
,通常具有時效性。可以拿來做 使用者重複登入時做後踢前、或者使用者閒置多久做登出的動作。
在iT邦幫忙中,登入前會給個Token,在登入的時候代入、驗證Token,代表這一次的連線訪問(Session)。
所以必須先取得這個Token。
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,傳帳號密碼進去。
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原始碼中,找到自己的姓名
、帳號
,那就是成功登入哩。