Golang - 如何寫爬蟲抓搜尋引擎的搜尋結果?

最近因為有抓搜尋引擎的搜尋結果的需求,自己動手用 Golang 實作了一個爬蟲。完成了抓取 Google 台灣搜尋結果的爬蟲後,為了讓後續撰寫 Yahoo 的爬蟲可以更順暢,我將架構抽取出來寫成獨立的框架。這一篇文章會以這個框架為核心,說明如何以 Golang 實作抓取搜尋引擎的搜尋結果的爬蟲。

抓取搜尋結果的爬蟲需要抓取的資料

通常會需要寫抓取搜尋結果的爬蟲,都是為了以自動化的方式瞭解某個關鍵字在搜尋引擎的排名狀況,因此通常只需要以下的資料:

  1. 某個關鍵字的某一頁的每一筆搜尋結果
  2. 每一筆搜尋結果的標題
  3. 每一筆搜尋結果的網址
  4. 每一筆搜尋結果的說明文字

如何使用此爬蟲框架?

此爬蟲框架的專案位址: A Framework For Writing Your Own Search Result Crawler in Golang

點擊上述的連結可以看到此專案的英文版使用說明。

此專案的 API 非常簡單,請看下面的 sample code :

  c := crawler.Crawler{
    Input: map[string][]int{
      "golang tutorial": []int{1, 2, 3},
      "seo":             []int{1, 2, 3, 5},
    },
    Parser: &parser.GoogleSearchParser{},
  }
  r := c.Start()
  r["seo"][0] //取得 seo 這個關鍵字的第一頁的所有搜尋結果。

首先,你需要初始化一個 Crawler struct ,而這個 struct 有兩個欄位,分別是 Input 以及 Parser。 只要呼叫 CrawlerStart method ,爬蟲便會開始進行抓取的工作並且傳回爬取的結果。

Input 為一個 key 為 string , value 為 []int 的 map。如上所示,key 為你要搜尋的關鍵字,而 value 則為你希望爬蟲爬取的頁數。

Parser 是一個 interface ,此 interface 的架構如下:

type Parser interface {
	GetSearchResultPageURL(string, int) string
	Parse(*goquery.Document, string, int, chan IntermediatePair)
}

你需要自己實作這個 interface ,而 GetSearchResultPageURL 這個 method 的用途為「根據關鍵字以及搜尋結果頁數求出對應的搜尋結果頁面的網址」,另外 Parse 這個 method 則是讓你使用 goquery 實作 Parsing 演算法的地方。

具體的 sample ,可以參考這個針對 Google 台灣搜尋設計的 Parser :Google Taiwan Search Parser,我就不針對這個專案的 code 做另外的說明了。

有一點要注意的是,在 parse 的過程中,每當你成功抓取出某一筆搜尋結果的資料後,要記得透過 channel 跟此框架溝通,這個框架會幫你整理 parse 的結果。

如果你有仔細閱讀上面的 code 的話,會發現 Parse 這個 method 其中一個 input 為 channel chan IntermediatePair 。那麼 IntermediatePair 是什麼呢?

IntermediatePair 的架構如下:

type IntermediatePair struct {
	Keyword string
	Page    int
	Index   int
	Result
}

IntermediatePair 有四個欄位,第一個為這一筆搜尋結果所屬的關鍵字,第二個為這一筆搜尋結果所屬的頁數,第三個為這一筆搜尋結果位於所屬頁數的位置(索引從 0 開始,因此假設是某一頁的第一筆,值就是 0 ,第二筆的話就是 1,依此類推),而最後一個則為 Result,架構如下:

type Result struct {
	Title       string
	URL         string
	Description string
}

Result 的第一個欄位為搜尋結果中的標題,第二個欄位為網址,第三個欄位則為搜尋結果中的說明文字。

了解上述的架構後,你就可以使用此框架實作自己的爬蟲了。更詳細的細節可以再自行參考上面提到的 Google Taiwan Search Parser,有任何問題也歡迎留言詢問。

comments powered by Disqus
分享至 Facebook 分享至 Google +