colly爬虫框架
- colly是用go实现的网络爬虫框架
- 这个框架与python的scrapy框架很像
- 数据清洗时,可以像jquery中一样用选择器来选择web元素
- 同时,清洗数据也可以使用xpath风格来定位元素
安装依赖
[ ~ ]# go get -u github.com/gocolly/colly/
colly中的Collector对象
collector := colly.NewCollector() // 实例化一个采集对象
colly中的回调函数
OnRequest
OnError
OnResponse
OnHTML
OnXML
OnScraped
Visit(Post等Requests方法)
Visit工作原理
- 获取配置,例如限制等
- 发起requests前先执行相应的handler,例如加载代理等
- 发起requests请求,也就是Visit中的fetch过程
- 发起requests前先执行相应的handler,例如OnHtml等
- 整个过程就是顺序流,也就是该框架封装了一些流水线,并暴露回调函数给开发者来重定义
异步实例
package t2
import (
"fmt"
"github.com/gocolly/colly"
"github.com/gocolly/colly/extensions"
"github.com/gocolly/colly/proxy"
"log"
"net/http"
)
// Spider 定义结构体
type Spider struct {
Collector *colly.Collector
}
// Init 初始化配置
func (s Spider) Init() {
s.Collector.Async = true
s.Collector.Limit(&colly.LimitRule{
Parallelism: 1, // 整个参数为并行度参数,但是并未理解其用法含义,不知道是会阻塞哪里
})
extensions.RandomUserAgent(s.Collector) // 设置随机UserAgent,以达到真实模拟浏览器
extensions.Referer(s.Collector)
//s.SetProxy() // 加载代理
s.SetTransport() // 配置Transport
s.OnResponse() // 加载自定义响应回调函数
s.OnError() // 加载自定义错误回调函数
}
// SetTransport Colly使用HTTP保持活动来提高抓取速度。它需要打开文件描述符,因此长时间运行的作业很容易达到max-fd限制
func (s Spider) SetTransport() {
s.Collector.WithTransport(&http.Transport{
DisableKeepAlives: true,
})
}
// SetProxy 设置代理,请重定义即可
func (s Spider) SetProxy() {
if _proxy, err := proxy.RoundRobinProxySwitcher(
"socks5://127.0.0.1:1337",
"socks5://127.0.0.1:1338",
"http://127.0.0.1:8080",
); err == nil {
s.Collector.SetProxyFunc(_proxy)
} else {
fmt.Println(err)
}
}
// Visit 封装Collector.Visit,并输出日志
func (s Spider) Visit(url string) {
//time.Sleep(time.Duration(1 * time.Second))
log.Println("准备访问地址:", url)
s.Collector.Visit(url)
}
// OnResponse 封装Collector.OnResponse,并输出日志,主要是自定义一些操作
func (s Spider) OnResponse() {
s.Collector.OnResponse(func(response *colly.Response) {
//time.Sleep(2 * time.Second)
log.Println("获得响应", response.StatusCode, response.Request.URL)
})
}
// OnError 封装Collector.OnError,并输出日志,主要是自定义一些操作
func (s Spider) OnError() {
s.Collector.OnError(func(response *colly.Response, err error) {
log.Println("错误响应",
response.StatusCode,
response.Request.URL,
response.Request.Headers,
response.Headers,
err,
)
})
}
// Wait 封装Collector.Wait,阻塞等待所有请求以及处理跑完
func (s Spider) Wait() {
s.Collector.Wait()
}
func Test() {
// 实例化
crawler := Spider{
Collector: colly.NewCollector(),
}
// 初始化配置
crawler.Init()
for i := 0; i < 10; i++ {
// 开始异步爬取
crawler.Visit(fmt.Sprintf("http://www.baidu.com/s?wd=%d", i))
}
// 等待所有的爬取结束
crawler.Wait()
fmt.Println("完成")
}
package main
import (
"fmt"
"spider-colly-test/t2"
"time"
)
func main() {
start := time.Now()
t2.Test() // 调取测试爬虫
end := time.Now()
fmt.Println(end.Sub(start)) // 看看总共耗时
}