上次的笔记介绍了如何使用go语言简单爬取网页代码,但是这种方法存在乱码问题,比如中文就无法读取。这一次笔记记录了这个问题的解决方案。
先在gopath中引入一个包:golang.org
分析main函数:
func main() {
//res 为结构体,储存了很多的信息
resp, err := http.Get("https://www.toutiao.com/?wid=1628221487217")
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Error status Code :%d", resp.StatusCode)
}
//获取响应体
bodyReader := bufio.NewReader(resp.Body)
//使用determiEncoding函数对获取的信息进行解析
e := determiEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader,e.NewDecoder())
//读取并打印获取的信息
result, err := ioutil.ReadAll(utf8Reader)
if err != nil {
panic(err)
}
fmt.Printf("%s", result)
}
可以看到main函数是没有太大的变化的。相较于之前,主要是增加了一部分代码:
//获取响应体
bodyReader := bufio.NewReader(resp.Body)
//使用determiEncoding函数对获取的信息进行解析
e := determiEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader,e.NewDecoder())
可以看到的是,代码中,先使用bodyReader获取了resp的响应体,然后在使用determinEncoding函数和 transform.NewReader函数对响应体进行处理,将其转变成utf8格式的字符串,转变完成之后再进行输出。
//处理获取的数据
func determiEncoding (r * bufio.Reader) encoding.Encoding {//Encoding编码是一种字符集编码,可以在 UTF-8 和 UTF-8 之间进行转换
//获取数据,Peek返回输入流的下n个字节
bytes, err := r.Peek(1024)
if err != nil {
log.Printf("fetch error :%v", err)
return unicode.UTF8
}
//调用DEtermineEncoding函数,确定编码通过检查最多前 1024 个字节的内容和声明的内容类型来确定 HTML 文档的编码。
e,_, _:= charset.DetermineEncoding(bytes,"")
return e
}
func main() {
//res 为结构体,储存了很多的信息
resp, err := http.Get("https://studygolang.com/")
if err != nil {
fmt.Println(err)
}
//使用get后必须使用close关闭,
//判断网页是否响应成功,defer后面的语句不会马上调用, 而是延迟到函数结束时调用
//defer 语句正好是在函数退出时执行的语句,所以使用 defer 能非常方便地处理资源释放问题。
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Error status Code :%d", resp.StatusCode)
}
//获取响应体
bodyReader := bufio.NewReader(resp.Body)
//使用determiEncoding函数对获取的信息进行解析
e := determiEncoding(bodyReader)
utf8Reader := transform.NewReader(bodyReader,e.NewDecoder())
//读取并打印获取的信息
result, err := ioutil.ReadAll(utf8Reader)
if err != nil {
panic(err)
}
fmt.Printf("%s", result)
}