Colly 请求上下文:让爬虫数据“随身携带”

2025-07-14 16:54 更新

想在请求之间传递自定义数据?用 Ctx.Put / Ctx.Get 就像给每个请求发一张“身份证”,URL、标题、分类随用随取!

一、示例:

编程狮课程频道,并携带课程分类:

package main


import (
    "fmt"


    "github.com/gocolly/colly/v2"
)


func main() {
    c := colly.NewCollector()


    // 1. 请求前把分类写进上下文
    c.OnRequest(func(r *colly.Request) {
        // 假设我们手动给不同课程加分类
        r.Ctx.Put("category", "Go语言")
        r.Ctx.Put("url", r.URL.String())
    })


    // 2. 响应后取出上下文里的数据
    c.OnResponse(func(r *colly.Response) {
        category := r.Ctx.Get("category")
        url      := r.Ctx.Get("url")
        fmt.Printf("分类[%s] → 地址[%s] 已抓取 %d 字节\n",
            category, url, len(r.Body))
    })


    // 3. 开始爬取
    c.Visit("https://www.w3cschool.cn/go")
}

运行结果:

分类[Go语言] → 地址[https://www.w3cschool.cn/go] 已抓取 12345 字节

二、3 个典型使用场景

场景 存什么 代码示例
列表 → 详情 课程名 r.Ctx.Put("title", e.Text)
分布统计 爬虫节点编号 r.Ctx.Put("node", "worker-3")
登录状态 Token r.Ctx.Put("jwt", token)

三、进阶:多收集器共享上下文

列表收集器把数据传给详情收集器:

listC := colly.NewCollector()
detailC := colly.NewCollector()


// 列表收集器:拿到链接后附带标题
listC.OnHTML("a.course", func(e *colly.HTMLElement) {
    ctx := colly.NewContext()
    ctx.Put("title", e.Text)
    detailC.Request("GET", e.Attr("href"), nil, ctx, nil)
})


// 详情收集器:读取标题
detailC.OnHTML("h1", func(e *colly.HTMLElement) {
    title := e.Request.Ctx.Get("title")
    fmt.Println("课程标题:", title)
})

四、常见坑 30 秒排查

原因 解决
取不到值 用错收集器 确保 Ctx.Put 和 Ctx.Get 在同一收集器或正确传递
并发冲突 多个 goroutine 写同一 key 使用唯一 key 或加锁
内存泄露 大量数据塞 Ctx 及时删除或用外部存储

五、1 分钟动手实验

  1. 打开 终端 → 新建 ctx.go
  2. 复制上方“中文注释”代码 → 运行。
  3. 观察终端:URL 和分类被一起打印,数据“随身携带”。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号