Golang在语言层级为我们准备了天然的高并发支持,因此也写个项目练练其并发使用。正好有位朋友想抓蛋壳网租房数据,我就趁这个机会写一个go的并发版爬虫项目。详细代码可移步至我github:https://github.com/slpslpslp/crawler。话不多说,进入正题。
项目结构
整体项目包含在crawler下,包括:
1.danke:目标网站。
- fetcher:处理url,得到返回结果。
- parser: 解析fetcher返回的结果
2.scheduler:任务调度器。
3.engine:实现Scheduler接口,建立工作引擎,中间件。
4.model:定义存储数据类型
5.persist:对数据做持久化处理(本例实现的是存储本地mysql)
6.main.go:项目入口
并发架构
注:该项目是我在油管上看到的一个教学视频学到的,是位google大牛授课,其项目是爬取相亲网站数据,上图即为其并发版架构(在我的项目项目代码中,worker还要包括数据持久化,即除了Parser,Fetcher还有ItemSaverSql,图上没注明)。由于目前该课被无良商家举报(为了恰饭),所以也找不到其视频源了。
整体:
- 将request传递给engine
- engine将request交给scheduler调度
- scheduler将request放入channel,然后由worker进行解析,将解析结果再放入channel,scheduler从channel中获取
parseResult继续调度任务
engine:
- 根据用户配置WorkerCount,开启多个goroutine实现并发
- 创建了供所有worker使用的channel
- 循环消费channel中的request,有就交给scheduler进行调度
scheduler:
- 持续将request放入channel,安排worker进行工作
爬虫讲解
蛋壳网的页面布局很简单https://www.danke.com/room/sz/d.html,如下图所示:
代码areaList.go解析大的行政区下的子区域url信息,由于蛋壳网数据都是在返回的html信息上,没有花里胡哨的ajax之类的。所以这里推荐使用htmlquery(真的很好用,谁用谁知道),获取途径
go get https://github.com/antchfx/htmlquery
代码area.go解析子区域的房屋url信息,https://www.danke.com/room/sz/d南山区-b桃园.html,如下图所示,获取该页的房屋列表中的每个入口url:
代码rentDetail.go解析每个房屋的详细信息,https://www.danke.com/room/1090110782.html,如下图所示,获取了红色表框的各项属性信息。
成果展示
golang爬虫真的很棒!
补充:
- 该项目的可扩展性很好,你可以利用本项目框架去爬取其他的网站。
- 本例中只是爬取了每个子区域的第一页房屋信息,没有翻页,如果想爬取所有数据,请自行完善。提示:在url后添加?page=n即可。
- 每个页面解析脚本都应该写测试单元(哎,太懒),因为网站的页面布局往往更新很快,如果哪天测试不通过,针对性修改解析脚本即可。