vlambda博客
学习文章列表

Go爬虫框架——Colly的简单学习

前言

colly是go使用最为广泛的框架,对其进行学习并使用!

特点

  • 简洁的API
  • 快速 (单核上>1k请求/秒)
  • 管理每个域的请求延时和最大并发性
  • Cookie和Session的自动处理
  • 同步/异步/并行 抓取
  • 分布式抓取
  • 缓存
  • 自动编码非Unicode响应
  • Robots.txt支持
  • 谷歌应用引擎支持

学习

colly的安装

#官方指令
go get -u github.com/gocolly/colly/...

包导入

import "github.com/gocolly/colly"

初次使用

Colly的主入口为一个Collector结构体(对象),一切操作均以它展开,我们以下称之为收集器!

Collector manages the network communication and responsible for the execution of the attached callbacks while a collector job is running.

**收集器**管理网络通信并且负责在任务执行时执行附加的回调函数。

首先,创建一个收集器对象,使用包自带的NewCollector()函数,该函数返回一个Collector类型指针,随后的一系列操作都是围绕这个指针进行!

c := colly.NewCollector()

然后就是官方所附带的一系列回调(Callback)函数

You can attach different type of callback functions to a Collector to control a collecting job or retrieve information.

可以使用不同的回调函数来控制一个任务或者重写相关信息(配置)

回调函数(方法)列表:

#在请求前调用
c.OnRequest(func(r *colly.Request) {
    fmt.Println("Visiting", r.URL)
})

#在请求期间出现错误是调用,相当于捕获异常?
c.OnError(func(_ *colly.Response, err error) {
    log.Println("Something went wrong:", err)
})

#在请求头部返回后调用
c.OnResponseHeaders(func(r *colly.Response) {
    fmt.Println("Visited", r.Request.URL)
})

#在请求主体(body)返回后调用
c.OnResponse(func(r *colly.Response) {
    fmt.Println("Visited", r.Request.URL)
})

#在请求主体返回后,并且主体内容为HTML时立即调用
c.OnHTML("a[href]"func(e *colly.HTMLElement) {
    e.Request.Visit(e.Attr("href"))
})

#上面发的回调函数的另一个示例
c.OnHTML("tr td:nth-of-type(1)"func(e *colly.HTMLElement) {
    fmt.Println("First column of a table row:", e.Text)
})

#当请求主体返回后,并且请求内容为HTML或者XML时立即调用,该函数优先级应小于OnHTML()(不过并未经过测试,仅推测)
c.OnXML("//h1"func(e *colly.XMLElement) {
    fmt.Println(e.Text)
})

#当以上函数执行结束后执行该函数
c.OnScraped(func(r *colly.Response) {
    fmt.Println("Finished", r.Request.URL)
})

上面可以看出来,方法的调用优先级应该是从上到下

回调函数配置完成后,使用Visit()方法开始进行爬取,

#指定要爬取的URL
c.Visit("http://go-colly.org/")

以下是一个简单示例,会爬取http://go-colly.org/中的<a>标签并且打印它的元素值(text)和href属性的值,同时会对爬取出的链接依次进行深度优先遍历爬取!

package main

import (
 "fmt"

 "github.com/gocolly/colly"
)

func main() {
 c := colly.NewCollector()
 // Find and visit all links
 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))
 })
 c.OnRequest(func(r *colly.Request) {
  fmt.Println("Visiting", r.URL)
 })
 c.Visit("http://go-colly.org/")
}

自定义配置

可在Selector对象创建时对其进行相关的自定义初始化操作,官方示例:

c2 := colly.NewCollector(
 colly.UserAgent("xy"),
 colly.AllowURLRevisit(),
)

该配置改变了用户代理即UA以及设置可以重新访问

不仅仅可以在对象创建时进行初始化操作,也可以在创建后进行覆写(修改)操作,官方示例:

c2 := colly.NewCollector()
c2.UserAgent = "xy"
c2.AllowURLRevisit = true

还可以通过环境变量的配置进行初始化时自动修改:

  • COLLY_ALLOWED_DOMAINS (逗号分割的域列表)
  • COLLY_CACHE_DIR (string)
  • COLLY_DETECT_CHARSET (y/n)
  • COLLY_DISABLE_COOKIES (y/n)
  • COLLY_DISALLOWED_DOMAINS (逗号分割的域列表)
  • COLLY_IGNORE_ROBOTSTXT (y/n)
  • COLLY_FOLLOW_REDIRECTS (y/n)
  • COLLY_MAX_BODY_SIZE (int)
  • COLLY_MAX_DEPTH (0代表无限)
  • COLLY_PARSE_HTTP_ERROR_RESPONSE (y/n)
  • COLLY_USER_AGENT (string)

网络配置

colly使用的go默认的http作为网络层,可以通过更改默认的HTTP roundtripper来对HTTP进行相关配置,官方示例:

c := colly.NewCollector()
c.WithTransport(&http.Transport{
 Proxy: http.ProxyFromEnvironment,
 DialContext: (&net.Dialer{
  Timeout:   30 * time.Second,
  KeepAlive: 30 * time.Second,
  DualStack: true,
 }).DialContext,
 MaxIdleConns:          100,
 IdleConnTimeout:       90 * time.Second,
 TLSHandshakeTimeout:   10 * time.Second,
 ExpectContinueTimeout: 1 * time.Second,
}



 
   
   
 

我们是程序员khaos,一群酷爱编程,乐于分享的小伙子,下期见~


「分享」「点赞」「在看」是最大支持