前言
任何刚接触爬虫编程的敌人可能都相熟或者或多或少理解过基于 Python 异步框架 Twisted 的爬虫框架 Scrapy。Scrapy 倒退了将近 7 年,是爬虫框架中的开山鼻祖,自然而然成为最受欢迎的也是利用最广的爬虫框架。对于 Scrapy 来说,其人造的劣势是反对并发,而且集成了 HTTP 申请、下载、解析、调度等爬虫程序中常见的功能模块,让爬虫工程师只专一于页面解析和制订抓取规定,在过后极大的简化了爬虫开发流程,进步了开发效率。
然而,Scrapy 并不是完满的,它依然有不少毛病。其中,它的模版定制化成为了制约 Scrapy 爬虫我的项目的双刃剑:一方面,Scrapy 形象出了各种必要的模块,包含爬虫(Spider)、抓取后果(Item)、中间件(Middleware)、管道(Pipeline)、设置(Setting)等,让用户能够间接上手依照肯定规定编写本人想要开发的爬虫程序;另一方面,这些高度形象的模块让整个爬虫我的项目显得比拟臃肿,每个爬虫我的项目都须要依照相应的模版生成好几个文件,导致配置、爬虫等治理起来绝对比拟凌乱。而且,Scrapy 在一些非凡场景例如分布式抓取时显得爱莫能助,因而很多高级爬虫工程师甚至须要更改 Scrapy 源码来满足业务要求。
为了解决这些问题,基于动态语言 Golang 的爬虫框架 Colly 在 2017 年末诞生了。尽管它的名气和受欢迎水平还不迭 Scrapy,但在试用之后我发现它有一个最特地的劣势:简略(Easiness)。依据 Colly 官网上的个性介绍,它有清新的 API(Clean API),疾速(Fast),人造反对分布式(Distributed),同步/异步/并行抓取(Sync/async/parallel scraping),丰盛的扩大(Extensions),以及更多个性。作者在简略的看了 Colly 的文档之后,尝试用 Colly 编写一些绝对简略的爬虫程序,发现编写结束后,每个网站的代码只蕴含一个文件。简而言之,它相当轻量级,不须要特地多的冗余代码就能够实现本人想要的逻辑。
下图是 Colly 和 Scrapy 在 Github 的 Star 数比照。能够看到 Colly 倒退较晚,star 数不到 Scrapy 的三分之一,但还在高速增长当中。本文将着重介绍这个年老而弱小的爬虫框架: Colly。
动态语言 Golang
gochanasyncioasync/await
上面是 Golang 的异步语法例子。
func run() {
fmt.Printf("hello world")
}
func main() {
go run()
}
上面是 Python 的异步语法例子。
import asyncio
async def main():
print('Hello ...')
await asyncio.sleep(1)
print('... World!')
# Python 3.7+
asyncio.run(main())
Golang 作为动态语言还有另一个十分重要的劣势,也就是其代码的可预测性(Predictability)。动态语言要求变量、参数以及函数返回后果都指定相应的类型,并且在编译的时候会查看类型的正确性,保障代码的可靠性。用动态语言编写的一个益处,就是能够让本人防止很多因为类型谬误导致的 bug。因而,对于可靠性和健壮性要求较高的大型项目来说,用动态语言编写会是比拟正当的抉择。编写 Golang 程序的时候,IDE 会依据类型或变量主动补全潜在的代码,是不是很香。相同,以 Python 为代表的动静语言,就没那么严格了。尽管 Python 是强类型语言,但它并不存在预编译的过程,因而无奈在编译时(Compile)检测出类型谬误。很多时候如果类型传入不对,都会在运行时(Runtime)导致谬误。网上流传的 “动静一时爽,重构火葬场”,说的也是这个情理。尽管动静语言(例如 Python)给抓取后果赋予了肯定的灵活性,但在我看来,大型爬虫我的项目用动态语言(例如 Golang)会是个更正当的抉择。
Colly
之前也介绍了,Colly 是一个由 Golang 编写的爬虫框架。Colly 其实是 Collector 或 Collecting 的昵称。它精简易用而弱小高效,正在逐步成为 Scrapy 以外的爬虫框架抉择。
咱们上面用一个例子来看一下它是如何做到的。(本文不是 Colly 的参考文档,仅心愿通过一些例子来介绍 Colly 的劣势和个性,要看所有 API 请参考 Colly 官网文档)
baidu_spider.go
package main
import (
"fmt"
"github.com/crawlab-team/crawlab-go-sdk/entity"
"github.com/gocolly/colly/v2"
)
func main() {
// 生成 colly 采集器
c := colly.NewCollector(
colly.AllowedDomains("www.baidu.com"),
colly.Async(true),
colly.UserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36"),
)
// 抓取后果数据钩子函数
c.OnHTML(".result.c-container", func(e *colly.HTMLElement) {
// 抓取后果实例
item := entity.Item{
"title": e.ChildText("h3.t > a"),
"url": e.ChildAttr("h3.t > a", "href"),
}
// 打印抓取后果
fmt.Println(item)
// 勾销正文调用 Crawlab Go SDK 存入数据库
//_ = crawlab.SaveItem(item)
})
// 分页钩子函数
c.OnHTML("a.n", func(e *colly.HTMLElement) {
_ = c.Visit("https://www.baidu.com" + e.Attr("href"))
})
// 拜访初始 URL
startUrl := "https://www.baidu.com/s?wd=crawlab"
_ = c.Visit(startUrl)
// 期待爬虫完结
c.Wait()
}
下面这个爬虫脚本,仅有 40 行代码。如果要用 Scrapy 来实现同样的性能,可能须要更多代码和文件目录。
能够从代码中看到,Colly 的爬虫程序编写非常简单,次要蕴含四个局部:
cOnHTMLcolly.HTMLElementc.Visityield scrapy.Requestc.Wait
go run baidu_spider.go
...
map[title:docker装置爬虫管理工具crawlab - kindvampire - 博客园 url:http://www.baidu.com/link?url=ueCY-MwzzGwaVqXw3Q18Fz8rEodI1P_mv60lRd8H0UZdFC4xVnVwWtsh-HpiwaOFI1zVjZFeVca]
map[title:crawlab python脚本关联mongodb后果集,实例_kai4024589..._CSDN博客 url:http://www.baidu.com/link?url=2wFQZaLoEk7OOTHrf1LOJcPiBAZEFETQYbjrqnrJi_Wfqdx-gPFIyjt2q3f7lTC-8A6SWz_l8zE6D8SBs1j0c4DOIwbdAw8i]
map[title:手把手教你如何用Crawlab构建技术文章聚合平台(一)_wei..._CSDN博客 url:http://www.baidu.com/link?url=nr9NOz2dqYFuaU5E1Zjz0OIfeeixSADNBNcHwj4dw9zypIky-9dVxd4RdzdS8-JMP7_X-LYpo0ydWmB8VNBmqq]
map[title:tikazyq-crawlab-master crawlab爬虫平台 适宜scrapy分布式部署... url:http://www.baidu.com/link?url=VibsGu0BinYAUR_96pWCmcELObAXIPn7rKprlc9HR_607_cuEbxlcShUHqXjOoV6dnc4pND5F0K]
map[title:手把手教你如何用Crawlab构建技术文章聚合平台(一) - 集体文章... url:http://www.baidu.com/link?url=SG6dJcLc20xIuiesjRIXu2XzGSR0N674BEnUTveJhYe5mRc9SFtggk-NL0pmAAa]
map[title:爬虫治理平台Crawlab v0.3.0公布(Golang版本) - 集体文章... url:http://www.baidu.com/link?url=TItw3zWB4jHCoGmoQMm01E7oP2WlwfX7BRMsA9WDhaxHeQZZDi3I8bZh_kgTfpNx4fhtf42_]
map[title:Crawlab 单节点服务集群搭建部署扼要教程 - 集体文章 - Segment... url:http://www.baidu.com/link?url=cuYEFA1zjqK1GiEmDCjwRMLDGFVKDsz6u4ljYjQol-VwDdr_cBS9Y3UlgChkyCuO7A_]
...
c.OnHTML
...
c.OnHTML(".result.c-container", func(e *colly.HTMLElement) {
item := entity.Item{
"title": e.ChildText("h3.t > a"),
"url": e.ChildAttr("h3.t > a", "href"),
}
// 后续解决抓取后果
PostProcess(item)
})
...
从这个例子中,你能够看到 Colly 的 API 非常简单、清新,而正是这种简略赋予了其极高的灵活性(Flexibility),让开发者能够在框架内做很多简单的事件。
当然,Colly 也是有毛病的。从目前的开发进度来看,Colly 仿佛还无奈反对动静渲染内容的抓取,例如 Ajax 数据渲染,而这个在 Scrapy 中是有现成的不少解决方案的。不过从最近的 Github 上的 Pull Request 来看,反对动静渲染内容应该会很快反对 chromedp 了,也就是反对调用 Chromium 来运行 JavaScript 内容。另外,Colly 仿佛还短少 Scrapy 中内置的日志零碎和数据统计模块,仿佛有些过于轻量化。
不过,咱们有理由置信,随着今后一直迭代,Colly 会变得越来越全面和弱小的。
与 Crawlab 集成
Crawlab 是反对任何语言和框架的分布式爬虫治理平台,实践上能运行所有类型的爬虫,包含 Colly 和 Scrapy。对 Crawlab 不理解的敌人能够查看 Crawlab 官网 以及 Github 首页)。
首先利用 Crawlab CLI 将爬虫文件上传。
~/projects/tikazyq/colly-crawlers/baidu(master*) » crawlab upload
go.mod
go.sum
baidu_spider.go
uploaded successfully
go run baidu_spider.go
期待一段时间,爬虫运行完结。咱们能够在日志中看到打印进去的后果。
并且,咱们还能够在 “后果” 中查看抓取到的后果数据。这些后果是默认保留在 MongoDB 数据库里的。
因而,用 Crawlab 来治理 Colly 爬虫是十分不便的。
总结
本文从介绍出名爬虫框架 Scrapy 的优缺点开始,引入了基于 Golang 的高效而简略的爬虫框架 Colly。而后咱们用一个百度搜索引擎抓取的例子,论述了 Colly 的劣势,也就是它精简而清新的 API 以及动态语言的健壮性,还有很多其余实用个性。Colly 的呈现,或者象征着爬虫开发者对简洁的谋求,所谓 “大道至简”,就是用简略而纯正的货色发明微小的价值。爬虫技术的倒退,是一个开发流程由简单变简略、而程序性能由简略变简单的过程。爬虫技术经验了 urllib/requests+BeautifulSoup 原始技术,到 Scrapy 的全能框架,再到现在的 Colly 的轻量级框架。而现在曾经有不少所谓的 “低代码” 甚至 “无代码” 爬虫平台了,例如 Crawlab 可配置爬虫、八爪鱼/后羿采集器。而智能化的爬虫抓取也在逐步变得风行。从这个角度来看,Colly 绝对于 Scrapy 应该是提高了。不过当初要说 Colly 是否取代 Scrapy 还为时过早,因为 Scrapy 还有很多优良的个性和生态是 Colly 临时无奈代替的。然而,Colly 目前正在高速倒退,逐步被开发者所理解,随着一直的反馈迭代,Colly 十分有后劲成为另一个爬虫界的必备技术。
参考
- Colly Github: https://github.com/gocolly/colly
- Colly 文档: https://pkg.go.dev/github.com…
- Crawlab Github: https://github.com/crawlab-te…
- Crawlab 官网: https://crawlab.cn
- Crawlab 演示: https://demo-pro.crawlab.cn