Introduction

本文对colly如何使用,整个代码架构设计,以及一些使用实例的收集。

Colly是Go语言开发的Crawler Framework,并不是一个完整的产品,Colly提供了类似于Python的同类产品(BeautifulSoupScrapy)相似的表现力和灵活性。

Colly这个名称源自 Collector 的简写,而Collector 也是 Colly的核心。

Colly Official Docs,内容不是很多,最新的消息也很就远了,仅仅是活跃在Github

Concepts

Architecture

从理解上来说,Colly的设计分为两层,核心层和解析层,

  • Collector :是Colly实现,该组件负责网络通信,并负责在Collector 作业运行时执行对应事件的回调。
  • Parser:这个其实是抽象的,官网并未对此说明,goquery和一些htmlquery,通过这些就可以将访问的结果解析成类Jquery对象,使html拥有了,XPath选择器和CSS选择器

通常情况下Crawler的工作流生命周期大致为

  • 构建客户端
  • 发送请求
  • 获取响应的数据
  • 将相应的数据解析
  • 对所需数据处理
  • 持久化

而Colly则是将这些概念进行封装,通过将事件注册到每个步骤中,通过事件的方式对数据进行清理,抽象来说,Colly面向的是过程而不是对象。大概的工作架构如图

event

通过上述的概念,可以大概了解到 Colly 是一个基于事件的Crawler,通过开发者自行注册事件函数来触发整个流水线的工作

Colly 具有以下事件处理程序:

  • OnRequest:在请求之前调用
  • OnError :在请求期间发生错误时调用
  • OnResponseHeaders :在收到响应头后调用
  • OnResponse: 在收到响应后调用
  • OnHTML:如果接收到的内容是 HTML,则在 OnResponse 之后立即调用
  • OnXML :如果接收到的内容是 HTML 或 XML,则在 OnHTML 之后立即调用
  • OnScraped:在 OnXML 回调之后调用
  • OnHTMLDetach:取消注册一个OnHTML事件函数,取消后,如未执行过得事件将不会再被执行
  • OnXMLDetach:取消注册一个OnXML事件函数,取消后,如未执行过得事件将不会再被执行

Reference

goquery

htmlquery

Utilities

简单使用

package mainimport ("fmt""github.com/gocolly/colly"
)func main() {// Instantiate default collectorc := colly.NewCollector(// Visit only domains: hackerspaces.org, wiki.hackerspaces.orgcolly.AllowedDomains("hackerspaces.org", "wiki.hackerspaces.org"),)// On every a element which has href attribute call callbackc.OnHTML("a[href]", func(e *colly.HTMLElement) {link := e.Attr("href")// Print linkfmt.Printf("Link found: %q -> %s\n", e.Text, link)// Visit link found on page// Only those links are visited which are in AllowedDomainsc.Visit(e.Request.AbsoluteURL(link))})// Before making a request print "Visiting ..."c.OnRequest(func(r *colly.Request) {fmt.Println("Visiting", r.URL.String())})// Start scraping on https://hackerspaces.orgc.Visit("https://hackerspaces.org/")
}

错误处理

package mainimport ("fmt""github.com/gocolly/colly"
)func main() {// Create a collectorc := colly.NewCollector()// Set HTML callback// Won't be called if error occursc.OnHTML("*", func(e *colly.HTMLElement) {fmt.Println(e)})// Set error handlerc.OnError(func(r *colly.Response, err error) {fmt.Println("Request URL:", r.Request.URL, "failed with response:", r, "\nError:", err)})// Start scrapingc.Visit("https://definitely-not-a.website/")
}

处理本地文件

word.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document title</title>
</head>
<body>
<p>List of words</p>
<ul><li>dark</li><li>smart</li><li>war</li><li>cloud</li><li>park</li><li>cup</li><li>worm</li><li>water</li><li>rock</li><li>warm</li>
</ul>
<footer>footer for words</footer>
</body>
</html>
package mainimport ("fmt""net/http""github.com/gocolly/colly/v2"
)func main() {t := &http.Transport{}t.RegisterProtocol("file", http.NewFileTransport(http.Dir(".")))c := colly.NewCollector()c.WithTransport(t)words := []string{}c.OnHTML("li", func(e *colly.HTMLElement) {words = append(words, e.Text)})c.Visit("file://./words.html")for _, p := range words {fmt.Printf("%s\n", p)}
}

使用代理交换器

通过 ProxySwitcher , 可以直接使用一批代理IP池进行访问了,然而这里只有RR,如果需要其他的均衡算法,需要有自己实现了

package mainimport ("bytes""log""github.com/gocolly/colly""github.com/gocolly/colly/proxy"
)func main() {// Instantiate default collectorc := colly.NewCollector(colly.AllowURLRevisit())// Rotate two socks5 proxiesrp, err := proxy.RoundRobinProxySwitcher("socks5://127.0.0.1:1337", "socks5://127.0.0.1:1338")if err != nil {log.Fatal(err)}c.SetProxyFunc(rp)// Print the responsec.OnResponse(func(r *colly.Response) {log.Printf("Proxy Address: %s\n", r.Request.ProxyURL)log.Printf("%s\n", bytes.Replace(r.Body, []byte("\n"), nil, -1))})// Fetch httpbin.org/ip five timesfor i := 0; i < 5; i++ {c.Visit("https://httpbin.org/ip")}
}

随机延迟

该功能可以对行为设置一种特征,以免被反扒机器人检测,并禁止我们,如速率限制和延迟

package mainimport ("fmt""time""github.com/gocolly/colly""github.com/gocolly/colly/debug"
)func main() {url := "https://httpbin.org/delay/2"// Instantiate default collectorc := colly.NewCollector(// Attach a debugger to the collectorcolly.Debugger(&debug.LogDebugger{}),colly.Async(true),)// Limit the number of threads started by colly to two// when visiting links which domains' matches "*httpbin.*" globc.Limit(&colly.LimitRule{DomainGlob:  "*httpbin.*",Parallelism: 2,RandomDelay: 5 * time.Second,})// Start scraping in four threads on https://httpbin.org/delay/2for i := 0; i < 4; i++ {c.Visit(fmt.Sprintf("%s?n=%d", url, i))}// Start scraping on https://httpbin.org/delay/2c.Visit(url)// Wait until threads are finishedc.Wait()
}

多线程请求队列

package mainimport ("fmt""github.com/gocolly/colly""github.com/gocolly/colly/queue"
)func main() {url := "https://httpbin.org/delay/1"// Instantiate default collectorc := colly.NewCollector(colly.AllowURLRevisit())// create a request queue with 2 consumer threadsq, _ := queue.New(2, // Number of consumer threads&queue.InMemoryQueueStorage{MaxSize: 10000}, // Use default queue storage)c.OnRequest(func(r *colly.Request) {fmt.Println("visiting", r.URL)if r.ID < 15 {r2, err := r.New("GET", fmt.Sprintf("%s?x=%v", url, r.ID), nil)if err == nil {q.AddRequest(r2)}}})for i := 0; i < 5; i++ {// Add URLs to the queueq.AddURL(fmt.Sprintf("%s?n=%d", url, i))}// Consume URLsq.Run(c)}

异步

默认情况下,Colly的工作模式是同步的。可以使用 Async 函数启用异步模式。在异步模式下,我们需要调用Wait 等待Collector 工作完成。

package mainimport ("fmt""github.com/gocolly/colly/v2"
)func main() {urls := []string{"http://webcode.me","https://example.com","http://httpbin.org","https://www.perl.org","https://www.php.net","https://www.python.org","https://code.visualstudio.com","https://clojure.org",}c := colly.NewCollector(colly.Async(),)c.OnHTML("title", func(e *colly.HTMLElement) {fmt.Println(e.Text)})for _, url := range urls {c.Visit(url)}c.Wait()}

最大深度

深度是在访问这个页面时,其页面还有link,此时需要采集到入口link几层的link?默认1

package mainimport ("fmt""github.com/gocolly/colly"
)func main() {// Instantiate default collectorc := colly.NewCollector(// MaxDepth is 1, so only the links on the scraped page// is visited, and no further links are followedcolly.MaxDepth(1),)// On every a element which has href attribute call callbackc.OnHTML("a[href]", func(e *colly.HTMLElement) {link := e.Attr("href")// Print linkfmt.Println(link)// Visit link found on pagee.Request.Visit(link)})// Start scraping on https://en.wikipedia.orgc.Visit("https://en.wikipedia.org/")
}

Reference

gocolly

colly

10分钟go crawler colly从入门到精通相关推荐

  1. 10分钟python爬虫_python scrapy 入门,10分钟完成一个爬虫

    在TensorFlow热起来之前,很多人学习python的原因是因为想写爬虫.的确,有着丰富第三方库的python很适合干这种工作. Scrapy是一个易学易用的爬虫框架,尽管因为互联网多变的复杂性仍 ...

  2. 10 分钟,带你快速入门前端三大技术(HTML、CSS、JavaScript)

    听到前端技术,不少朋友一定会感到有些陌生.但其实,前端,你每天都在接触. 你正在使用的APP,你正在浏览的网页,这些你能看到的界面,都属于前端. 而前端最重要的三大技术,HTML,CSS,JavaSc ...

  3. C# 10分钟完成百度人脸识别——入门篇

    今天我们来盘一盘人脸注册.人脸识别等相关操作,这是一个简单入门教程. 话不多说,我们进入主题: 完成人脸识别所需的步骤: 注册百度账号api,创建自己的应用: 创建vs控制台应用程序,引入动态链接库: ...

  4. 10分钟零基础带你入门Ribbon小项目-啥?小白都能看懂?

    文章目录 一.前置说明及其框架搭建 1.思路详解 2.框架搭建 二.代码编写 1.编写五个pom文件 1.1.父pom文件 1.2.子模块pom 2.编写启动类 3.application.yml文件 ...

  5. c# imager让图片有圆角unity_C# 10分钟完成百度图片提取文字(文字识别)——入门篇...

    现在图片文字识别已经很成熟了,比如qq长按图片,点击图片识别就可以识别图片的文字,将不认识的.文字数量大的.或者不能赋值的值进行二次可复制功能. 我们现在就基于百度Ai开放平台进行个人文字识别,dem ...

  6. C# 10分钟完成百度翻译(机器翻译)——入门篇

    C# 10分钟完成百度翻译(机器翻译)--入门篇 1.注册百度账号api,创建自己的Api应用 2.创建vs控制台应用程序 3.编写程序并调试 post请求工具类 文本翻译-通用版 文本翻译-词典版 ...

  7. java书籍_学习Java最好的10本书,从入门到精通

    在当代,学习Java等编程课程的主要方式是视频资源,如果你想学,在网上五分钟之内就可以找到一堆学习视频,瞬间将你的硬盘填满.但是这些课程质量良莠不齐,对于小白来说很难辨别好坏. 但是书籍不同,书籍都是 ...

  8. UWP开发入门(十九)——10分钟学会在VS2015中使用Git

    原文:UWP开发入门(十九)--10分钟学会在VS2015中使用Git 写程序必然需要版本控制,哪怕是个人项目也是必须的.我们在开发UWP APP的时候,VS2015默认提供了对微软TFS和Git的支 ...

  9. Spring Boot 永远滴神!10分钟快速入门

    为什么是 SpringBoot 因为目前开发 WEB 应用,Spring Boot 是启动 Spring 项目最快最流行的方式了.无论我们要构建一个什么样的应用,它都可以让我们尽可能快的启动运行起来. ...

最新文章

  1. 云计算安全解决方案白皮书(二)
  2. 解决Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array.
  3. C# dynamic使用
  4. 学会这个用这个做PPT,把24小时的工作变成1秒!高效神器保住你的发际线~
  5. modelsim(1):经常使用的测试设计的结构
  6. SpringMVC拦截器之拦截器接口方法演示
  7. CSS Grid网格布局全攻略
  8. 没错!Python杀死了Excel!
  9. 第一节 9布尔运算符
  10. 聚焦消费和产业两大物联网赛道,腾讯连连全新升级
  11. 用于SAO Utils桌面网页挂件的Live2D看板娘
  12. 学习笔记(1):《微电子器件》陈星弼(第四版)第1章 半导体物理基础及基本方程
  13. 瑞星搜狐畅游合作 “云安全”首次嵌入网游客户端
  14. KeyCue Mac 快捷键辅助工具
  15. 新猿木子李:0基础学python培训教程 Python操作Excel之写入数据
  16. 正方形螺旋线python代码_python绘制正方形螺旋线
  17. QQ空间玩吧HTML5游戏引擎使用比例分析
  18. mmorpg游戏设计之2D游戏地图的九宫格子
  19. 用Windows自带工具给U盘4k对齐
  20. VSCode配置MPX开发

热门文章

  1. 基于Java毕业设计业余足球队服务平台源码+系统+mysql+lw文档+部署软件
  2. MySQL之账号管理、建库、四大引擎以及数据类型、建表、约束
  3. springboot踩坑日记-java: User-specified option “-proc:none“ is ignored for “xxx-xxx-common“. This compil
  4. 真Unity3d_立个Flag_PBR学习路径
  5. 小学四年级计算机教学工作总结,四年级数学教学工作总结
  6. 【时空序列预测paper】ConvLSTM:A Machine Learning Approach for Precipitation Nowcasting
  7. 知识图谱入门 【八】- 语义搜索
  8. P1.2高清小间距LED显示屏600*337.5mm箱体价格
  9. Lotus Notes 邮件归档设置
  10. 爬虫获取西刺免费高匿代理