前言
任何刚接触爬虫编程的敌人可能都相熟或者或多或少理解过基于 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
Colly 是基于动态语言 Golang 开发的。家喻户晓,Golang 也是一个比拟年老的语言,仅有 13 年历史(相较而言,Python 有将近 30 年历史)。Golang 人造反对并发(Concurrency),要起一个协程(Coroutine),只须要在调用函数前加一个 go
关键词即可,非常简单。当然,Golang 还有其余很棒的个性,例如通道(chan
)。不过对于爬虫来说反对并发是十分重要的,因为一个高效的爬虫须要尽可能多的占用网络带宽资源,Golang 的并发个性给编写爬虫框架来说带来了劣势。反观 Python,如果要实现并发的话须要做很多工作,包含利用 asyncio
库和从 JavaScript ES7 借鉴过去的 async/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 的爬虫程序编写非常简单,次要蕴含四个局部:
- 生成 Colly 采集器(Collector)
c
,并传入一些配置信息; OnHTML
钩子函数,蕴含colly.HTMLElement
元素实例,这里次要是解决抓取后果的逻辑;c.Visit
拜访函数,相似 Scrapy 中的yield scrapy.Request
;c.Wait
期待函数,期待 Colly 爬虫程序执行结束。
创立好之后,在所在目录执行 go run baidu_spider.go
,即可运行百度搜寻“crawlab”关键词爬虫。运行后果相似如下。
...
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_]
...
你可能会纳闷,Pipeline 和 Middleware 等 Scrapy 中定义的模块去哪里了?其实,你须要留神的是,这些模块并不是必须的,只是大佬们在开发爬虫过程中总结进去的一些实用的逻辑,形象进去了而已。如果要在 Colly 中实现 Pipeline,间接在 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
而后在 Crawlab 的爬虫详情界面中输出执行命令 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