我們之前說過了,我們先從單任務(wù)版開始進(jìn)行。。。。。
這里我們先給單任務(wù)版爬蟲定一個(gè)小目標(biāo)
- 獲取并打印所在城市第一頁用戶的詳細(xì)信息
stevendeAir:js_crawler steven$ pwd
/Users/steven/learngo/src/learn/js_crawler
stevendeAir:js_crawler steven$ ls
main.go
我們首先給這個(gè)項(xiàng)目建一個(gè)文件夾,名字為js_crawler,之后建了一個(gè)main.go文件
// main.go
package main
import (
"net/http"
"io/ioutil"
"fmt"
)
func main() {
// 首先我們使用get請求,拿到響應(yīng)的結(jié)果resp
resp, err := http.Get(
"http://www.zhenai.com/zhenghun")
// 對錯(cuò)誤的處理,go就是這么處理的不像其他的語言應(yīng)try
if err != nil{
panic(err)
}
// 請求完成以后我們需要把這個(gè)流關(guān)上
defer resp.Body.Close()
// 如果請求不是200我們把狀態(tài)碼打出來
if resp.StatusCode != http.StatusOK{
fmt.Println("Error: Status code",
resp.StatusCode)
return
}
// 讀取Body里面的內(nèi)容
all, err := ioutil.ReadAll(resp.Body)
if err != nil{
panic(err)
}
fmt.Printf("%s\n", all)
}

很好,我們的頁面打印出來了但是我們發(fā)現(xiàn)它是亂碼,這個(gè)是為什么呢?應(yīng)該怎么辦呢?
這是因?yàn)镚o語言都是utf8編碼,但是我們這個(gè)網(wǎng)頁的是gbk編碼所以就出現(xiàn)了亂碼,沒關(guān)系我們解決它。。。。
我們只需要把gbk轉(zhuǎn)成utf8就可以了,這里我們需要下載兩個(gè)包看下面
stevendeAir:js_crawler steven$ gopm get -g -v golang.org/x/text
[GOPM] 05-27 12:14:41 [ INFO] App Version: 0.8.8.0307 Beta
[GOPM] 05-27 12:14:41 [ INFO] Local repository path: /Users/steven/.gopm/repos
[GOPM] 05-27 12:14:41 [ INFO] Indicated GOPATH: /Users/steven/learngo
[GOPM] 05-27 12:14:41 [ INFO] /Users/steven/.gopm/repos/golang.org/x/text
[GOPM] 05-27 12:14:41 [DEBUG] Skipped installed package: golang.org/x/text@branch:<UTD>
[GOPM] 05-27 12:14:41 [ WARN] Package in GOPATH has version control: golang.org/x/text
[GOPM] 05-27 12:14:41 [ INFO] 0 package(s) downloaded, 0 failed
它說Skipped installed package,這說明我已經(jīng)安裝過了,現(xiàn)在可以直接使用了
我們把之前的resp.Body改成轉(zhuǎn)碼以后的就可以了
utf8Reader := transform.NewReader(
resp.Body, simplifiedchinese.GBK.NewDecoder())
// 讀取Body里面的內(nèi)容
all, err := ioutil.ReadAll(utf8Reader)

ok,到此呢我們的問題解決了,但是呢這么做并不通用,因?yàn)橐院笪覀兛赡軙?huì)有其它的編碼也會(huì)出現(xiàn)亂碼,那么怎么才能通用呢,我們可以去獲取網(wǎng)頁上面的charset然后轉(zhuǎn)成utf8是不是就可以了呢?其實(shí)有時(shí)候會(huì)有變態(tài)的網(wǎng)頁連meta也沒有我們怎么做呢?其實(shí)這里我們用到了Go語言的一個(gè)包可以直接獲取網(wǎng)頁的編碼看下面。。。。
stevendeAir:js_crawler steven$ gopm get -g -v golang.org/x/net/html
[GOPM] 05-27 12:23:05 [ INFO] App Version: 0.8.8.0307 Beta
[GOPM] 05-27 12:23:05 [ INFO] Local repository path: /Users/steven/.gopm/repos
[GOPM] 05-27 12:23:05 [ INFO] Indicated GOPATH: /Users/steven/learngo
[GOPM] 05-27 12:23:05 [ INFO] /Users/steven/.gopm/repos/golang.org/x/net
[GOPM] 05-27 12:23:05 [DEBUG] Skipped installed package: golang.org/x/net/html@branch:<UTD>
同樣的我也安裝好了,直接用一把。。
// 定義一個(gè)解析的函數(shù)
func determineEncoding(r io.Reader) encoding.Encoding{
// 我們可以把它放到Peek里面下回繼續(xù)讀
// 如果我們不用Peek,它讀完1024以后就不會(huì)在讀這1024個(gè)字節(jié)了
// Peek 返回緩存的一個(gè)切片,該切片引用緩存中前 n 字節(jié)數(shù)據(jù)
bytes, err := bufio.NewReader(r).Peek(1024)
if err != nil{
panic(err)
}
e, _, _ := charset.DetermineEncoding(bytes, "")
return e
}
然后把上面的resp.Body處理一下。。。。
e := determineEncoding(resp.Body)
utf8Reader := transform.NewReader(
resp.Body, e.NewDecoder())
為了讓大家可以清楚的看到我的目錄結(jié)構(gòu),我會(huì)在代碼的上面放上這段代碼所在的文件位置,方便你的查看。比如說上面這段代碼在main.go文件里面,在開發(fā)的過程中我也會(huì)把代碼層次結(jié)構(gòu)發(fā)給大家,不用擔(dān)心跟不上。。。。。你真實(shí)寫代碼的時(shí)候,上面的main.go就不需要加了!?。?!
怎么樣這一節(jié)看完了,你跟著操作了嘛,成功了嘛!?。。。?!