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

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

首先分析到请求url为:

http://www.zhenai.com/zhenghun

接下来用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))
}

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

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

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

所以在github上下载:

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

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

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

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

mkdir -p $GOPATH/src/golang.org/x
cd $GOPATH/src/golang.org/x
git clone https://github.com/golang/net

那么代码就变成这样:

package main

import (
  "fmt"
  "io/ioutil"
  "net/http"
  "golang.org/x/text/transform"
  //"golang.org/x/text/encoding/simplifiedchinese"
  "io"
  "golang.org/x/text/encoding"
  "bufio"
  "golang.org/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
}

运行后就看不到乱码了:

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

原文发布于微信公众号 - 我的小碗汤(mysmallsoup)

原文发表时间:2018-06-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程思想之路

Android6.0源码分析之View(一)

目前对于view还处于学习阶段,本来打算学习结束之后再写一篇进行总结,但是发现自己自制力太差,学习效率太低,所以在此,边学边写博客,不仅督促自己完成对view的...

1968
来自专栏Felix的技术分享

HTML5动态时钟

8645
来自专栏布尔

ExtJS4预览:渲染过程重构和标准化

在过去的四年,ExtJs代码库已经进化了,新组件被加进来,编码标准也改进了。在这个过程中,为了重构旧组件有必要经常追溯回去以保证他们也被改进。 在ExtJS4...

21410
来自专栏前端说吧

Vue-自定义事件之—— 子组件修改父组件的值

3645
来自专栏施炯的IoT开发专栏

《101 Windows Phone 7 Apps》读书笔记-BOOK READER

课程内容 Ø编页 ØList Picker Ø拉伸List Box 控件中的条目     本章的Book Reader应用程序为Jane Austen的经典小...

1916
来自专栏张高兴的博客

张高兴的 UWP 开发笔记:汉堡菜单进阶

4406
来自专栏我有一个梦想

ClistCtrl用法及总结(由怎样隐藏ListCtrl列表头的排序小三角形这个bug学习到的知识)

1 怎样隐藏ListCtrl列表头的排序小三角形 在创建控件是加入|LVS_NOSORTHEADER风格即可。 一下是用法总结: 本文根据本人在项目中的应用,来...

3345
来自专栏林德熙的博客

win10 uwp 进度条 Marquez

本文将告诉大家,如何做一个带文字的进度条,这个进度条可以用在游戏,现在我做的挂机游戏就使用了他。

751
来自专栏企鹅号快讯

使用多个Python库开发网页爬虫(一)

21CTO社区导读:在本篇文章里,我们将讨论使用Python进行网页抓取以及如何引用多个库,如Beautifusoup,Selenium库,以及JavaScri...

4036
来自专栏程序员的诗和远方

在React Native中优雅的使用iconfont

React Native大火大热,其中为了解决图标,易于修改,换颜色,高清等需求,iconfont的应用更是必不可少。 React Native中的ic...

5944

扫码关注云+社区

领取腾讯云代金券