先上程式碼:
Github
Go語言其實很早就有了,但是最近才火起來。有Google爸爸做靠山,這個語言的前景是非常被看好的。
不同於流行的java,php,javascript,python等語言,Go語言是更接近於C/C++的底層語言。不需要虛擬機器或者容器之類的執行環境。這就為它的執行效率和可控性提供了很大的保障。
Go語言的語法很簡單,而且提供了常用的標準庫,更優雅的API。這是它相對於C/C++語言很大的進步之一。極大的降低了使用者的學習成本。
Go的優勢在於天生的非同步能力。能夠通過極為簡潔優雅的方式實現多執行緒的程式設計。而Go對於變數的種種限制,簡直就是某些強迫症患者的福音。
學習Go語言之後,用它寫了一個簡單的爬蟲以做練習。
首先呢,要爬的網站是4chan,恩恩,可以幫你開啟新世界的大門的那種。
上來先定義一個結構體:
//ThreadItem 帖子資料
type ThreadItem struct {
url string //帖子路徑
content string //帖子內容
imgs []string //帖子圖片
}
複製程式碼
要爬取網頁,首先要通過http下載網頁內容:
func httpGet(url string) (content string, statusCode int) {
resp, err1 := http.Get(url)
if err1 != nil {
statusCode = -100
return
}
defer resp.Body.Close()
data, err2 := ioutil.ReadAll(resp.Body)
if err2 != nil {
statusCode = -200
return
}
statusCode = resp.StatusCode
content = string(data)
return
}
複製程式碼
http是GO語言提供的標準庫之一,可以發起和接受http請求。ioutil也是標準庫之一,功能顧名思義。 使用defer關鍵字,來保證在執行後關閉http連線。
通過httpGet方法可以請求到頁面資料。這個方法在有兩處使用,第一處是在開始呼叫此方法,獲取到一個index頁面。然後在index頁面中解析出帖子路徑後,通過此方法填充ThreadItem中的content欄位。
第二件事則是通過正規表示式解析出頁面中有價值的資料,在此爬蟲中利用了兩個正則:
var (
//圖片正規表示式
imageItemExp = regexp.MustCompile(`src="//i\.4cdn\.org/s/[0123456789]+s\.jpg"`)
//帖子路徑正規表示式
threadItemExp = regexp.MustCompile(`"thread/[0123456789]+"`)
)
複製程式碼
此處以解析帖子路徑為例,展示正則的使用方式:
//解析正規表示式,返回引數tds是一個陣列
tds := threadItemExp.FindAllStringSubmatch(content, 10000)
var tdStr = make([]string, 0)
//去掉引號,並放到一維陣列中
for _, t := range tds {
var n = strings.Replace(t[0], "\"", "", -1)
tdStr = append(tdStr, n)
}
var threads = make([]ThreadItem, 0)
//組裝帖子結構體
for _, t := range tdStr {
threads = append(threads, ThreadItem{url: "http://boards.4chan.org/s/" + t})
}
return threads
複製程式碼
通過此方法就成功的獲取到了一堆的帖子結構體。
go語言傲嬌的取消了“類”這種東西,但是還是允許給結構體指定方法。在實際的呼叫上,和平常的類感受是差不多的。
最後一件事情就是下載圖片了。對於go來說,下載圖片和下載網頁內容的操作是基本一致的,都是通過http.Get方法來獲取資料。所以不再累述。在此值得一說的是對檔案系統的操作。
最核心的程式碼就這三行:
//建立目錄
err := os.Mkdir(dir, os.ModePerm)
//建立檔案
file, err := os.Create(dir + "/" + filename)
//寫入資料
file.Write(data)
複製程式碼
看原始碼可知Go中對於error的處理還是挺繁瑣的,簡簡單單的三行程式碼需要進行好多次的錯誤判斷。不過從另一個角度上來說也算強制的進行防禦性程式設計,提高了程式碼可可靠性。
至此一個GO語言的爬蟲就初步完成了。雖然很簡單,但是也算是學習Go語言道路上的第一步。