因项目需要,要对网络上某些信息进行抓取,以便加工后做数据分析。提到爬虫框架,知名度最高的当属基于Python的爬虫框架 Scrapy。但是由于本人对 Python 并不熟悉,并且暂时也不准备去深入学习,因此不在考虑范围。同时也是基于学习的目的,因此选择了 Golang 方向。基于 Golang 的成熟爬虫框架其实并不多,因此在选择上不用太纠结,就用 Go-Colly 了。

由于墙的原因,安装 Go-Colly 并不是非常顺利,至少不像官网介绍的一条命令就OK了。下面基于 CentOS-7.2/Golang-v1.11 环境,对安装做下简单的说明。

1. 安装 Golang-v1.11

Golang 的安装还是非常简单的,直接选择编译好的安装包即可。

# 下载
wget https://dl.google.com/go/go1.11.1.linux-amd64.tar.gz
# 放在对应目录
tar -zxf go1.11.1.linux-amd64.tar.gz -C /usr/local
# 配置环境变量
# vim /etc/profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=/data/golang

2. 安装 Go-Colly

参考官网手册,直接执行安装命令。

go get -u github.com/gocolly/colly/...

执行完后看到如下报错

package github.com/gocolly/colly
    imports golang.org/x/net/html: unrecognized import path "golang.org/x/net/html" (https fetch: Get https://golang.org/x/net/html?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
package github.com/gocolly/colly
    imports golang.org/x/net/html/charset: unrecognized import path "golang.org/x/net/html/charset" (https fetch: Get https://golang.org/x/net/html/charset?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
package github.com/gocolly/colly
    imports google.golang.org/appengine/urlfetch: unrecognized import path "google.golang.org/appengine/urlfetch" (https fetch: Get https://google.golang.org/appengine/urlfetch?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

这是由于防火墙的原因,安装过程中无法下载到某些以依赖的包。那么我们就手动来安装下。
Golang 的包在 Github 上有对应的镜像,因此我们一一手动下载下来放到对应目录即可。

# net/text
mkdir -p /data/golang/src/golang.org/x
cd /data/golang/src/golang.org/x
git clone https://github.com/golang/net
git clone https://github.com/golang/text
# protobuf
mkdir -p /data/golang/src/github.com/golang
cd /data/golang/src/github.com/golang
git clone https://github.com/golang/protobuf
# appengine
mkdir /data/golang/src/google.golang.org
cd /data/golang/src/google.golang.org
git clone https://github.com/golang/appengine.git

至此,所需的包都已经配置完成。如果还有报错的,按照提示继续安装即可。

3. 试运行下demo

以下是个最基本的示例,抓取本博客的信息。

vim gocolly.go

package main

import (
    "fmt"
    "github.com/gocolly/colly"
)

func main() {
    // 实例化
    c := colly.NewCollector(
        // 限定域名
        colly.AllowedDomains("blog.phpha.com"),
        // 最大深度
        colly.MaxDepth(1),
    )

    // On every a element which has href attribute call callback
    c.OnHTML("a[href]", func(e *colly.HTMLElement) {
        link := e.Attr("href")
        // Print link
        fmt.Printf("Link found: %q -> %s\n", e.Text, link)
        // Visit link found on page
        // Only those links are visited which are in AllowedDomains
        c.Visit(e.Request.AbsoluteURL(link))
    })

    // Before making a request print "Visiting ..."
    c.OnRequest(func(r *colly.Request) {
        fmt.Println("Visiting", r.URL.String())
    })

    // Start scraping on http://blog.phpha.com/
    c.Visit("http://blog.phpha.com/")
}

运行结果如下

# go run gocolly.go
Visiting http://blog.phpha.com/
Link found: "PHPHa" -> http://blog.phpha.com/
Link found: "首页" -> http://blog.phpha.com/
Link found: "归档" -> http://blog.phpha.com/archives
Visiting http://blog.phpha.com/archives
...

标签:CentOS Golang Gocolly