今天來繼續做比昨天更具 沒意義的事。
我想透過爬蟲設定帳號密碼,來自動登入 iT邦幫忙 這個優質論壇。
模擬使用者登入
首先要觀察敵情,登入自己的帳號密碼來看看整個流程
按下登入按鈕。
F12Network
(可以透過設定 Setting Preserve Log來保留日誌,就算跳頁、刷新也不會消失)
login
login
剛剛所輸入的帳號密碼就在眼前!
沒錯,就是他了,警察叔叔!這裡有人密碼露出來了!
_token"accountpasswordmethod="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。
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
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)
}
}
姓名帳號