大家好,我是渔夫子。

今日给大家推荐一个高性能的网络爬虫结构:Geziyor。该结构能够用来抓取网站内容并从中提取出结构化的数据。其用处极为广泛,能够用于数据发掘、监控以及自动化测试。
项目地址:github.com/geziyor/gez…

接下来咱们来看Geziyor结构的运用和特点。

基本运用

该结构运用很简单,便是配置对应的选项发动即可。以抓取网址quotes.toscrape.com/ 的内容为例。

指定要抓取的网址

package main
import (
	"github.com/geziyor/geziyor"
)
func main() {
	geziyor.NewGeziyor(&geziyor.Options{
		StartURLs: []string{"http://quotes.toscrape.com/"},
	}).Start()
}

运转上面的代码,就能够抓取StartURLs变量中网址的内容了。那么,怎么处理抓取后的成果呢?

指定抓取成果解析函数

经过 ParseFunc选项指定解析成果的函数。咱们指定解析函数为quotesParse,如下:

package main
import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/geziyor/geziyor"
	"github.com/geziyor/geziyor/client"
)
func main() {
	geziyor.NewGeziyor(&geziyor.Options{
		StartURLs: []string{"http://quotes.toscrape.com/"},
		ParseFunc: quotesParse,
	}).Start()
}
func quotesParse(g *geziyor.Geziyor, r *client.Response) {
	r.HTMLDoc.Find("div.quote").Each(func(i int, s *goquery.Selection) {
		g.Exports <- map[string]interface{}{
			"text":   s.Find("span.text").Text(),
			"author": s.Find("small.author").Text(),
		}
		fmt.Printf("debug-s:%+v\n", s)
	})
	if href, ok := r.HTMLDoc.Find("li.next > a").Attr("href"); ok {
		g.Get(r.JoinURL(href), quotesParse)
	}
}

因为ParseFunc的类型是func(g *Geziyor, r *client.Response),所以在quotesParse函数中的入参也是*Geziyor*client.Response

在成果解析函数中,咱们还能够做入库操作,来永久保存。当然,还能够将成果导出成json或csv等。

指定成果导出函数

geziyor.Options选项中,经过Exporters参数可执行要导出的格局目标,就能够将解析的成果导出成对应的格局。如下是导出json格局:

package main
import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/geziyor/geziyor"
	"github.com/geziyor/geziyor/client"
	"github.com/geziyor/geziyor/export"
)
func main() {
	geziyor.NewGeziyor(&geziyor.Options{
		StartURLs: []string{"http://quotes.toscrape.com/"},
		ParseFunc: quotesParse,
		Exporters: []export.Exporter{&export.JSON{}},
	}).Start()
}
func quotesParse(g *geziyor.Geziyor, r *client.Response) {
	r.HTMLDoc.Find("div.quote").Each(func(i int, s *goquery.Selection) {
		g.Exports <- map[string]interface{}{
			"text":   s.Find("span.text").Text(),
			"author": s.Find("small.author").Text(),
		}
		fmt.Printf("debug-s:%+v\n", s)
	})
	if href, ok := r.HTMLDoc.Find("li.next > a").Attr("href"); ok {
		g.Get(r.JoinURL(href), quotesParse)
	}
}

运转该段代码后,能够看到在当时目录下会多了一个out.json的文件,这个文件便是输出的json格局的内容。当然,能够经过export.JSON目标中的FileName特点指定要输出的文件。

咱们看下Exporters的类型是一个export.Exporter的切片,代表能够将一个成果一起输出多种格局。一起,export.Exporter是一个接口类型,也便是说只要实现了该export.Exporter的接口,就能够扩展导出的格局。如下:

type Exporter interface {
	Export(exports chan interface{}) error
}

指定请求的并发量

经过选项参数中的ConcurrentRequests: 就能够指定并发量。这里的并发是指的当咱们指定了多个要抓取的地址时,能够发动多个协程来做抓取使命。如下:

func main() {
	geziyor.NewGeziyor(&geziyor.Options{
		ConcurrentRequests: 10,
		StartURLs: []string{"http://quotes.toscrape.com/"},
		ParseFunc: quotesParse,
		Exporters: []export.Exporter{&export.JSON{}},
	}).Start()
}

更多选项配置,能够检查geziyor.Options中的配置。就不一一介绍了。

总结

经过该结构,还能够学习怎么控制并发数,怎么经过中间件的方法来进步结构的扩展性,所以还是值得学习的。

特别说明:你的重视,是我写下去的最大动力。点击下方公众号卡片,直接重视。重视送《100个go常见的错误》pdf文档、经典go学习材料。