iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Software Development

30天學會Golang系列 第 20

Day20 - Go的正則表達式與簡易爬蟲

  • 分享至 

  • xImage
  •  

簡易爬蟲

透過 day19 的內容,我們可以根據事先定義好的形式來抓取要特定資料,那麼今天就做的小專案,透過正則表達式來抓取我們在鐵人30天的標題。
首先這是我們 鐵人30天的網址,可能之後會隨著文章的新增而與後面的結果不同,因此會附上一個目前我在爬蟲時的網路源碼,會附在 代碼連結中,簡易爬蟲的流程如下:

  • 查看我們的目標網站源碼
  • 尋找目標規律
  • 定義正則表達式
  • 透過程式碼讀取網路資訊
  • 將資訊匹配正則表達式並獲取目標資料

首先我們的目標網站畫面如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20150797pljJ6KHCn7.png

透過右鍵點擊檢查原始碼:

https://ithelp.ithome.com.tw/upload/images/20221001/20150797pYyIXrlxba.png

原始碼畫面如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20150797d2U6SsUphG.png

目標:

https://ithelp.ithome.com.tw/upload/images/20221001/20150797Kue6IIltNS.png

看到標題出現時的規律前都會有下面這一行,我們就可以利用這個來定義正則表達式

class="qa-list__title-link"

以下附上程式碼,並且裡面有當時測試的源碼檔案,名為 itTitle.html

const url = "https://ithelp.ithome.com.tw/users/20150797/ironman/5271?page=2"

// 從網路上讀取資料
func Fetcher(url string) ([]byte, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("new request error %s", err)
	}

	// 有些 url 需要有 User-Agent 的資訊,否則會出現 403 的問題,鐵人30 就需要這個東西
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36")

	resp, err := client.Do(req)

	if err != nil {
		return nil, fmt.Errorf("client error %s", err)
	}

	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("wrong status code: %d", resp.StatusCode)
	}

	return ioutil.ReadAll(resp.Body)
}

// 從檔案讀取資料
func ReadFile(fileName string) ([]byte, error) {
	file, err := ioutil.ReadFile(fileName)
	if err != nil {
		return nil, fmt.Errorf("read file error: %s", err)
	}

	return file, err
}

// 正則表達式
var HotQuestionRe = `class=\"qa-list__title-link\">\s*([^<]*)`

// 檔案路徑
var filePath = "day20/itTitle.html"

func main() {
	// 從網路獲取文章
	html, err := Fetcher(url)

	// 從文檔讀取文章
	// html, err := ReadFile(filePath)

	if err != nil {
		fmt.Println(err)
	}

	//解析正则表達式,如果成功返回解释器
	reg := regexp.MustCompile(HotQuestionRe) // \t表空格,[^\t]表示除了空格外,其他都可
	if reg == nil {
		fmt.Println("regexp err")
		return
	}

    // 文章匹配正則表達式
	result := reg.FindAllSubmatch(html, -1)
	var s []string
	for _, v := range result {
		trimV := strings.TrimSpace(string(v[1]))
		s = append(s, trimV)
	}

    // 輸出結果
	for i := range s {
		fmt.Println(s[i])
	}
}

輸出結果為:

Day11 - Go的文檔制作
Day12 - Go的 goroutine
Day13 - Go的 channel (上)
Day14 - Go的 channel (下)
Day15 - Go的 WaitGroup
Day16 - Go的 Mutex (互斥鎖)
Day17 - Go的 Select
Day18 - Go的 package
Day19 - Go的正則表達式
第20天報到,裡面有提到網路跟文檔讀寫,雖然還沒介紹到,之後來介紹一下,後來發現其實也有現成的爬蟲資料庫,明天來研究一下

參考來源

  1. https://coding.m.imooc.com/classindex.html?cid=180

代碼連結

https://github.com/luckyuho/ithome30-golang/tree/main/day20


上一篇
Day19 - Go的正則表達式
下一篇
Day21 - Go的網路爬蟲 colly
系列文
30天學會Golang31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言