Colly 多收集器:让爬虫分工协作
2025-07-11 15:21 更新
任务复杂时,把“一个工人”拆成“多个工人”——一个翻目录、一个拿详情,效率翻倍,代码更清爽。
一、为什么要用多个收集器?
想象你在爬 编程狮课程频道:
任务 | 单收集器 | 多收集器 |
---|---|---|
翻列表页 → 取 1000 门课程链接 | 逻辑混杂 | 列表收集器专职翻页 |
点进详情页 → 拿课程标题/价格 | 回调地狱 | 详情收集器专心解析 |
结果 | 代码臃肿、难调试 | 结构清晰、易维护 |
二、快速上手:3 步完成“分工”
1. 创建两个收集器
package main
import (
"github.com/gocolly/colly/v2"
)
func main() {
// ① 列表收集器:只负责翻页 + 提取详情页链接
listC := colly.NewCollector(
colly.AllowedDomains("www.w3cschool.cn"),
)
// ② 详情收集器:只负责解析课程详情
detailC := colly.NewCollector(
colly.AllowedDomains("www.w3cschool.cn"),
)
}
2. 克隆收集器(配置共享)
如果两个收集器配置几乎一样,用 Clone()
一行搞定:
base := colly.NewCollector(
colly.UserAgent("编程狮爬虫 1.0"),
colly.AllowedDomains("w3cschool.cn"),
)
listC := base.Clone() // 复用 UA 与域名白名单
detailC := base.Clone()
3. 传递上下文(共享数据)
列表页拿到课程 ID 后,传给详情收集器:
// 列表收集器:拿到链接 → 交给详情收集器
listC.OnHTML("a.course-card", func(e *colly.HTMLElement) {
detailURL := e.Attr("href")
// 把课程名放进上下文,后续直接取
ctx := colly.NewContext()
ctx.Put("courseName", e.Text)
detailC.Request("GET", detailURL, nil, ctx, nil)
})
// 详情收集器:用上下文里的数据
detailC.OnHTML("h1", func(e *colly.HTMLElement) {
courseName := e.Request.Ctx.Get("courseName")
println("课程名:", courseName, " 标题:", e.Text)
})
三、完整示例:爬“编程狮课程”
package main
import (
"github.com/gocolly/colly/v2"
)
func main() {
// 公共配置
base := colly.NewCollector(
colly.UserAgent("编程狮-多收集器-Demo"),
colly.AllowedDomains("www.w3cschool.cn"),
)
listC := base.Clone()
detailC := base.Clone()
// 列表页:翻页 + 发链接
listC.OnHTML("a.course-item", func(e *colly.HTMLElement) {
ctx := colly.NewContext()
ctx.Put("courseName", e.Text)
detailC.Request("GET", e.Attr("href"), nil, ctx, nil)
})
// 详情页:解析
detailC.OnHTML("h1", func(e *colly.HTMLElement) {
courseName := e.Request.Ctx.Get("courseName")
println("抓到课程:", courseName)
})
// 从第一页开始
listC.Visit("https://www.w3cschool.cn/course")
}
运行结果(示意):
抓到课程:Go 入门教程
抓到课程:Python 爬虫实战
...
四、调试小技巧:一眼看出哪个收集器
在日志里加 collector.ID
:
listC.OnRequest(func(r *colly.Request) {
println("[列表收集器]", r.URL)
})
detailC.OnRequest(func(r *colly.Request) {
println("[详情收集器]", r.URL)
})
五、实战选型速查表
场景 | 推荐做法 |
---|---|
列表 + 详情 | 两个收集器 + Clone() |
不同域名/UA | 独立 NewCollector |
需要上下文 | Request(..., ctx) |
六、1 分钟动手实验
- 打开 Go 环境 → 新建文件。
- 复制“完整示例” → 把域名换成你正在学的站点 → 运行。
- 观察终端:列表、详情日志是否交替出现。
以上内容是否对您有帮助:
更多建议: