使用Go语言实现爬虫功能

4,687 阅读3分钟

先上代码:

Github


Go语言其实很早就有了,但是最近才火起来。有Google爸爸做靠山,这个语言的前景是非常被看好的。

不同于流行的java,php,javascript,python等语言,Go语言是更接近于C/C++的底层语言。不需要虚拟机或者容器之类的运行环境。这就为它的执行效率和可控性提供了很大的保障。

Go语言的语法很简单,而且提供了常用的标准库,更优雅的API。这是它相对于C/C++语言很大的进步之一。极大的降低了使用者的学习成本。

Go的优势在于天生的异步能力。能够通过极为简洁优雅的方式实现多线程的编程。而Go对于变量的种种限制,简直就是某些强迫症患者的福音。

学习Go语言之后,用它写了一个简单的爬虫以做练习。


首先呢,要爬的网站是4chan,恩恩,可以帮你打开新世界的大门的那种。

上来先定义一个结构体:

//ThreadItem 帖子数据
type ThreadItem struct {
	url     string   //帖子路径
	content string   //帖子内容
	imgs    []string //帖子图片
}

要爬取网页,首先要通过http下载网页内容:

func httpGet(url string) (content string, statusCode int) {
	resp, err1 := http.Get(url)
	if err1 != nil {
		statusCode = -100
		return
	}
	defer resp.Body.Close()
	data, err2 := ioutil.ReadAll(resp.Body)
	if err2 != nil {
		statusCode = -200
		return
	}
	statusCode = resp.StatusCode
	content = string(data)
	return
}

http是GO语言提供的标准库之一,可以发起和接受http请求。ioutil也是标准库之一,功能顾名思义。 使用defer关键字,来保证在执行后关闭http连接。

通过httpGet方法可以请求到页面数据。这个方法在有两处使用,第一处是在开始调用此方法,获取到一个index页面。然后在index页面中解析出帖子路径后,通过此方法填充ThreadItem中的content字段。


第二件事则是通过正则表达式解析出页面中有价值的数据,在此爬虫中利用了两个正则:

var (
	//图片正则表达式
	imageItemExp = regexp.MustCompile(`src="//i\.4cdn\.org/s/[0123456789]+s\.jpg"`)
	//帖子路径正则表达式
	threadItemExp = regexp.MustCompile(`"thread/[0123456789]+"`)
)

此处以解析帖子路径为例,展示正则的使用方式:

	//解析正则表达式,返回参数tds是一个数组
	tds := threadItemExp.FindAllStringSubmatch(content, 10000)
	var tdStr = make([]string, 0)
	//去掉引号,并放到一维数组中
	for _, t := range tds {
		var n = strings.Replace(t[0], "\"", "", -1)
		tdStr = append(tdStr, n)
	}
	var threads = make([]ThreadItem, 0)
	//组装帖子结构体
	for _, t := range tdStr {
		threads = append(threads, ThreadItem{url: "http://boards.4chan.org/s/" + t})
	}
	return threads

通过此方法就成功的获取到了一堆的帖子结构体。

go语言傲娇的取消了“类”这种东西,但是还是允许给结构体指定方法。在实际的调用上,和平常的类感受是差不多的。


最后一件事情就是下载图片了。对于go来说,下载图片和下载网页内容的操作是基本一致的,都是通过http.Get方法来获取数据。所以不再累述。在此值得一说的是对文件系统的操作。

最核心的代码就这三行:

//创建目录
err := os.Mkdir(dir, os.ModePerm)
//创建文件
file, err := os.Create(dir + "/" + filename)
//写入数据
file.Write(data)

看源码可知Go中对于error的处理还是挺繁琐的,简简单单的三行代码需要进行好多次的错误判断。不过从另一个角度上来说也算强制的进行防御性编程,提高了代码可可靠性。


至此一个GO语言的爬虫就初步完成了。虽然很简单,但是也算是学习Go语言道路上的第一步。