colly爬虫框架
- colly是用go实现的网络爬虫框架
- 这个框架与python的scrapy框架很像
- 数据清洗时,可以像jquery中一样用选择器来选择web元素
- 同时,清洗数据也可以使用xpath风格来定位元素
安装依赖
[ ~ ]
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"
)
type Spider struct {
Collector *colly.Collector
}
func (s Spider) Init() {
s.Collector.Async = true
s.Collector.Limit(&colly.LimitRule{
Parallelism: 1,
})
extensions.RandomUserAgent(s.Collector)
extensions.Referer(s.Collector)
s.SetTransport()
s.OnResponse()
s.OnError()
}
func (s Spider) SetTransport() {
s.Collector.WithTransport(&http.Transport{
DisableKeepAlives: true,
})
}
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)
}
}
func (s Spider) Visit(url string) {
log.Println("准备访问地址:", url)
s.Collector.Visit(url)
}
func (s Spider) OnResponse() {
s.Collector.OnResponse(func(response *colly.Response) {
log.Println("获得响应", response.StatusCode, response.Request.URL)
})
}
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,
)
})
}
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))
}