Day25 Golang 爬蟲框架 colly 模擬使用者登入

今天來繼續做比昨天更具 沒意義的事。

我想透過爬蟲設定帳號密碼,來自動登入 iT邦幫忙 這個優質論壇。

模擬使用者登入

首先要觀察敵情,登入自己的帳號密碼來看看整個流程

觀察敵情

按下登入按鈕。

F12Network

熟門熟路

(可以透過設定 Setting Preserve Log來保留日誌,就算跳頁、刷新也不會消失)

Preserve Log1
Preserve Log2

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)
	}
}

姓名帳號