背景

前些天用Python实践了一下爬虫功能,强大的requests库、re库、beautifulsoup库和scrapy框架以及其附属的分布式数据库配套库,开发起来十分高效。对于复杂的爬虫规则和验证规则,Python的相关生态也能提供很好的解决方案。回到golang,也想尝试是否能用go语言也构建一个基本爬虫,看实现上会有多大差异。

目标功能

获取 http://razil.cc 首页上的网站名称元素内容。
目标内容为“后端小筑”

基本结构

由于是基本的定向爬虫,类比Python的结构是
requests库 + re库
即基本请求后处理转码,再通过正则获得需要的数据
在go实现的结构如下:

  • [net/http] 基本请求
  • [mahonia] 第三方库实现编码转换
  • [regexp] 正则匹配数据

代码实现

package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"

	encodingConvert "github.com/DennisMao/mahonia"
)

func SimpleScrapy(url string) (string, error) {
	//http请求
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}

	//获取响应数据
	if resp.StatusCode != 200 {
		return "", errors.New("resp statuscode = :" + fmt.Sprint(resp.StatusCode))
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", nil
	}

	//编码转换
	content := encodingConvert.NewEncoder("utf-8").ConvertString(string(respBody))
	//正则
	re, _ := regexp.Compile(`\<a.+a\>`)

	txts := re.FindAllString(content, 10) //获取到所有 <a>标签
	if len(txts) == 0 {
		return "", nil
	}

	reClass, _ := regexp.Compile(`class=\"site-header-title\"`) //筛选 <a>标签中 class="site-header-title" 的标签
	for _, txt := range txts {
		if reClass.MatchString(txt) {
			//返回数据
			reTitle, _ := regexp.Compile(`\>.+\<`)  //获取元素中的内容
			titleRaw := reTitle.FindString(txt)
			return titleRaw[1 : len(titleRaw)-1], nil
		}
	}
	return "", nil
}

func main() {
	url := "http://razil.cc"
	title, err := SimpleScrapy(url)
	if err != nil {
		fmt.Println(err.Error())
	}
	fmt.Println("网站Title = ", title)
}

打印输出: simpleScrapy输出结果

总结

通过初探,可以了解使用Go基本库可以轻松进行爬虫的编写。与Python相比,Go语言没有那么多丰富的库供我们调用,但是通过对Python相关库的理解,我们也可以自己用Go来“翻译”相关的库。另外由于语言异常处理的风格不同,Go这块的代码里会稍多一些。
项目地址: https://github.com/DennisMao/gospider

文章目录