這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
上一節已經說明了要做什麼,以及整個小程式的目錄結構,接下來就開始編碼部分。
首先在入口檔案中引入項目下的包crawldata,然後調用其中抓取資料的函數,暫時取名為Crawl:
package mainimport ( "fmt" "indiepic/crawldata")func main () { // 使用crawldata包裡面的Crawl()抓取需要的資料存到資料庫 crawldata.Crawl() fmt.Println("主函數")}
然後就是實現包crawldata裡面的Crawl函數。將該函數放在crawldata.go檔案中:
package crawldataimport ( "fmt")func Crawl() { fmt.Println("包crawldata中的Crawl函數")}
查看網站 http://www.gratisography.com/,然後審查元素找到某張圖片,在圖片主要包含了src、data-original、width、height、alt等資訊,首先要明確一點的是這個網站使用了圖片的lazy載入(在每個li標籤上可以看出來),所以真正的圖片URL是data-original指定的值而不是src,src值會在圖片載入完成之後被賦為data-original的值。另外在網站上有一個分類,所以需儲存一下每一張圖片的分類,在抓取的時候也是直接通過分類去抓取。
因此我們需要定義一個結構體來表示每一條資料包含的資料,以及用於儲存全部資料的一個切片,然後在Crawl函數中使用。如下:
package crawldataimport ( "fmt" "github.com/PuerkitoBio/goquery" "strconv" s "strings")// 定義一個儲存一條資料的結構體type ImageData struct { Src string Tp string Title string Width int Height int}// 定義切片用於儲存抓取的全部資料type ImageDatas []ImageDatafunc Crawl() { fmt.Println("包crawldata中的Crawl函數") // 定義一個切片儲存所有資料 var datas ImageDatas // 抓取資料 imageDatas := CrawlData(&datas)}
在上面的Crawl函數中又調用了一個CrawlData函數,該函數接受一個用於儲存資料的datas變數,並返回抓取後的所有資料。
/* 該函數用來抓取資料,並將儲存的值返回到主函數*/func CrawlData(datas *ImageDatas) (imageDatas ImageDatas) { imageDatas = *datas // 規定抓取時匹配的元素 var types = [...]string{ "people", "objects", "whimsical", "nature", "urban", "animals"} doc, err := goquery.NewDocument("http://www.gratisography.com/") if err != nil { fmt.Printf(err.Error()) } for _, tp := range types { doc.Find("#container ul").Find(s.Join([]string{".", tp}, "")).Each(func(i int, s *goquery.Selection) { img := s.Find("img.lazy") src, _ := img.Attr("data-original") title, _ := img.Attr("alt") width, _ := img.Attr("width") height, _ := img.Attr("height") // 將寬度和高度的字串類型轉為數值型 wd, error := strconv.Atoi(width) if error != nil { fmt.Println("字串轉換成整數失敗") } hg, error := strconv.Atoi(height) if error != nil { fmt.Println("字串轉換成整數失敗") } // fmt.Printf("Review %d: %s - %s - %s - %d - %d\n", i, src, tp, title, wd, hg) imageData := ImageData{src, tp, title, wd, hg} imageDatas = append(imageDatas, imageData) }) } return}
定義了一個數組types用於存放分類,然後根據分類去獲得各分類下的圖片。
資料抓取使用 goquery,在運行之前需要使用如下命令擷取goquery
go get github.com/PuerkitoBio/goquery
goquery的用法和jQuery很類似,直接通過網頁中的一些標籤、class、id等擷取,更多的使用方法可以查看文檔。
這裡還使用了strconv中的函數轉換類型,使用strings處理字串。這兩個都是GO的內建包,不需要其他運行命令擷取。
在Crawl函數中可以使用for輸出看擷取到的資料,如:
func Crawl() { // 定義一個切片儲存所有資料 var datas ImageDatas // 抓取資料 imageDatas := CrawlData(&datas) for i := 0; i < len(imageDatas); i++ { fmt.Println(imageDatas[i].Src, imageDatas[i].Title, imageDatas[i].Tp, imageDatas[i].Height, imageDatas[i].Width) } // 或者 for _, imageData := range imageDatas { fmt.Println(imageData.Src, imageData.Title, imageData.Tp, imageData.Height, imageData.Width) } // 將資料插入資料庫 // InsertData(&imageDatas)}
下一步實現將擷取的資料插入資料庫的方法InsertData(&imageDatas)。