29

Goquery爬虫工具

 5 years ago
source link: https://studygolang.com/articles/16479?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Goquery安装使用

http://blog.studygolang.com/2015/04/go-jquery-goquery/

  • Goquery需要手动安装,可以直接去github上下载,也可以通过go get github.com/PuerkitoBio/goquery获取
  • Goquery的爬虫功能依赖 net/html 包,好像是被墙了,需要去 https://github.com/golang/net 下载zip包,You can also manually git clone the repository to $GOPATH/src/ golang.org/x/net .记得要把 net-master 改成net
  • 如果出现 dial tcp no such host,记得先ping 一下,可能是网络做了拦截,要用代理
  • 有些网站会做反爬虫的措施(比如豆瓣网),记得断点调试看返回码,403就是禁止访问了

案例1 从糗事百科里面爬笑话

  1. 先通过url获取到document,再遍历document来操作数据

  2. 根据类选择器,获取到所有的 class=content的元素,然后再遍历,把每个元素都封装成一个Selection

  3. 再通过 Selection.Text()来获取文本内容

  4. 对Selection支持强大的过滤条件和遍历,具体可以参考网站上面的

  5. 常用的函数示例

//获取到selection下面的超链接的 文本内容
contentSelection.Find("a").Text()

// 获取到该超链接的herf属性值
href, _ := contentSelection.Find("a").Attr("href")

简易的写法,直接从Url里面获取Document,缺点是如果反爬虫了,err仍然为nil

doc, err := goquery.NewDocument("http://www.qiushibaike.com")
    if err != nil{
        log.Fatal(err)
    }
    doc.Find(".content").Each(func(i int, s *goquery.Selection){
        fmt.Println(s.Text())
    })

改良的写法,先获取ResponseBody,判断返回码之后,再从ResponseBody里面取数据

url:= "http://www.qiushibaike.com"
    resp, err := http.Get(url)
    if err != nil {panic(err)}
    if resp.StatusCode != 200 {
        fmt.Println("err")
    }
    doc, err := goquery.NewDocumentFromReader(resp.Body)
    doc.Find(".content").Each(func(i int, s *goquery.Selection){
        fmt.Println(s.Text())
    })

案例2 从Golang社区爬标题

  1. html部分代码
<dl class="topics dl-horizontal">
        <div class="topic">
            <dd class="right-info">
                <div class="title">
                    <a href="/topics/4134" title="GCTT:Go中文翻译组成立了,期待大家的加入">GCTT:Go中文翻译组成立了,期待大家的加入</a>
                </div>
                <div class="meta">
                    <span style="color: #ff7700; border: 1px solid #ff7700;">置顶</span> • 
                    <a href="/go/notice" class="node" title="公告">公告</a>
                    <a href="/user/polaris" title="polaris" class="author"><strong>polaris</strong></a>
                </div>
            </dd>
        </div>
</dl>
  1. 爬虫代码

    先按照 topics大类下面的 topic小类获取到元素,再通过 title类和元素选择器选中我们的目标元素,再通过Text()获取到内容

doc, err := goquery.NewDocument("http://studygolang.com/topics")
    if err != nil {
        log.Fatal(err)
    }
    doc.Find(".topics .topic").Each(func(i int, contentSelection *goquery.Selection) {
        title := contentSelection.Find(".title a").Text()
        log.Println("第", i+1, "个帖子的标题:", title)
    })

字符集转换工具mahonia

直接 go get github.com/axgle/mahonia ;或者 https://github.com/axgle/mahonia 手动下载安装

使用

func UseNewEncoder(src string,oldEncoder string,newEncoder string) string{
    srcDecoder := mahonia.NewDecoder(oldEncoder)
    desDecoder := mahonia.NewDecoder(newEncoder)
    resStr:= srcDecoder.ConvertString(src)
    _, resBytes, _ := desDecoder .Translate([]byte(resStr), true)
    return string(resBytes)
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK