Go 分享一个写爬虫,走过的坑

ghn645568344 · 2016年12月13日 · 最后由 gyorou 回复于 2016年12月15日 · 8772 次阅读

本人小白,最近在网上一大堆赞美 go 的文章,今天闲下来看了看,捣鼓了一下,简单了看了下语法,没深看,习惯边写边学单看没意思😜 ,我个人觉得熟悉一门语言最快的方式就是写爬虫😎 ,废话不多说,开始主题

开始安装之旅,go 的安装和 ruby 大同小异,唯一认为比较坑的,是需要自己配 GOPATH 与工作空间,本来打算用一个类似于 rvm 的一个东东(gvm),结果发现这个被墙了,而且到处找没找到国内有相关的源,坑爹呀有木有😤 ,瞬间感觉还是 ruby 大法好,没办法还是老老实实的安装吧

访问下载地址http://www.golangtc.com/download,32 位系统下载 go1.x.x.linux-386.tar.gz,64 位系统下载 go1.x.x.linux-amd64.tar.gz, 假定你想要安装 Go 的目录为 $GO_INSTALL_DIR,后面替换为相应的目录路径。 解压缩 tar.gz 包到安装目录下:tar zxvf go1.X.x.linux-amd64.tar.gz -C $GO_INSTALL_DIR。 设置 PATH,export PATH=$PATH:$GO_INSTALL_DIR/go/bin 然后执行 go 如果出现一大串 关于 go 的内容,恭喜你安装成功了

开始爬虫
之前用 RUBY 写过一段时间爬虫,所以本能的在 go 上搜索下有没有类似的东东,结果发现真有“httpclient”。。。。。解析页面用 goquery 每次都是爬豆瓣练手😷

package main

import (
    "fmt"
    "github.com/PuerkitoBio/goquery"
    "github.com/ddliu/go-httpclient"
)

func main() {

    res, _ := httpclient.Get("https://www.douban.com/search", map[string]string{
        "q": "123",
    })
    doc, _ := goquery.NewDocumentFromReader(res.Body)
    name := doc.Find("h1").Text()
    fmt.Println(name)
    doc.Find(".result").Each(func(i int, s *goquery.Selection) {
        fmt.Println(i)
        title := s.Find("h3").Find("a").Text()
        url, _ := s.Find("h3").Find("a").Attr("href")
        fmt.Println("--------" + title + "---" + url)
    })

}

省略了异常处理,代码不多就短短的几行,花费了半天的时间🕥 ,唯一卡住时间的是调用 goquery 方法的时候,各种报错,各种查。。。都没找到,后来看了看官方的文档。。才搞明白应该用 NewDocumentFromReader 这个方法。。。。 分享出来,希望向我一样的小白想用 GO 写爬虫的人,少走点弯路

我觉得写爬虫最大的坑是,爬着爬着,IP 就被封了...

不错,但是一点都不 go。go 的精髓在于并发。 请尝试使用 go routine 实现并发爬取,使用 go channel 控制爬取粒度。

doc, _ := goquery.NewDocumentFromReader(res.Body)
name := doc.Find("h1").Text()

NewDocumentFromReader 函数返回的 err 不应该被忽略,或者 doc 要做 nil 判断,否则有可能报 panic

http client 那里也是如此

#2 楼 @gyorou 感觉爬虫用并发,只是加快了被封的速度😥

#3 楼 @miclle 受教了,当时是为了简单测试下,省去了异常处理

😓 你这个最多算个 httpclient,离被封还有些距离,请继续努力。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号