用go语言爬取珍爱网 | 第一回_golang

我们来用go语言爬取“珍爱网”用户信息。

首先分析到请求url为:

http://www.zhenai.com/zhenghun

用go语言爬取珍爱网 | 第一回_git_02

接下来用go请求该url,代码如下:

package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func main() {

//返送请求获取返回结果
resp, err := http.Get("http://www.zhenai.com/zhenghun")

if err != nil {
panic(fmt.Errorf("Error: http Get, err is %v\n", err))
}

//关闭response body
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
fmt.Println("Error: statuscode is ", resp.StatusCode)
return
}

body, err := ioutil.ReadAll(resp.Body)

if err != nil {
fmt.Println("Error read body, error is ", err)
}

//打印返回值
fmt.Println("body is ", string(body))
}

运行后会发现返回体里有很多乱码:

用go语言爬取珍爱网 | 第一回_kubernetes_03

在返回体里可以找到 即编码为gbk,而go默认编码为utf-8,所以就会出现乱码。接下来用第三方库将其编码格式转为utf-8。

由于访问/x/text需要梯子,不然报错:

用go语言爬取珍爱网 | 第一回_golang_04

所以在github上下载:

mkdir -p $GOPATH/src//x
cd $GOPATH/src//x
git clone https:///golang/text.git

然后将gbk编码转换为utf-8,需要修改代码如下:

utf8Reader := transform.NewReader(resp.Body, simplifiedchinese.GBK.NewDecoder())
body, err := ioutil.ReadAll(utf8Reader)

考虑到通用性,返回的编码格式不一定是gbk,所以需要对实际编码做判断,然后将判断结果转为utf-8,需要用到第三方库/x/net/html,同样的在github上下载:

mkdir -p $GOPATH/src//x
cd $GOPATH/src//x
git clone https:///golang/net

那么代码就变成这样:

package main

import (
"fmt"
"io/ioutil"
"net/http"
"/x/text/transform"
//"/x/text/encoding/simplifiedchinese"
"io"
"/x/text/encoding"
"bufio"
"/x/net/html/charset"
)

func main() {

//返送请求获取返回结果
resp, err := http.Get("http://www.zhenai.com/zhenghun")

if err != nil {
panic(fmt.Errorf("Error: http Get, err is %v\n", err))
}

//关闭response body
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
fmt.Println("Error: statuscode is ", resp.StatusCode)
return
}

//utf8Reader := transform.NewReader(resp.Body, simplifiedchinese.GBK.NewDecoder())
utf8Reader := transform.NewReader(resp.Body, determinEncoding(resp.Body).NewDecoder())
body, err := ioutil.ReadAll(utf8Reader)

if err != nil {
fmt.Println("Error read body, error is ", err)
}

//打印返回值
fmt.Println("body is ", string(body))
}

func determinEncoding(r io.Reader) encoding.Encoding {

//这里的r读取完得保证resp.Body还可读
body, err := bufio.NewReader(r).Peek(1024)

if err != nil {
fmt.Println("Error: peek 1024 byte of body err is ", err)
}

//这里简化,不取是否确认
e, _, _ := charset.DetermineEncoding(body, "")
return e
}

运行后就看不到乱码了:

用go语言爬取珍爱网 | 第一回_golang_05

今天先爬到这里,明天将提取返回体中的地址URL和城市,下一节见。


作者简洁


作者:小碗汤,一位热爱、认真写作的小伙,目前维护原创公众号:『我的小碗汤』,专注于写golang、docker、kubernetes等知识等提升硬实力的文章,期待你的关注。 转载说明:务必注明来源(注明:来源于公众号:我的小碗汤, 作者:小碗汤)