任務(wù)復(fù)雜時(shí),把“一個(gè)工人”拆成“多個(gè)工人”——一個(gè)翻目錄、一個(gè)拿詳情,效率翻倍,代碼更清爽。
想象你在爬 編程獅課程頻道:
任務(wù) | 單收集器 | 多收集器 |
---|---|---|
翻列表頁 → 取 1000 門課程鏈接 | 邏輯混雜 | 列表收集器專職翻頁 |
點(diǎn)進(jìn)詳情頁 → 拿課程標(biāo)題/價(jià)格 | 回調(diào)地獄 | 詳情收集器專心解析 |
結(jié)果 | 代碼臃腫、難調(diào)試 | 結(jié)構(gòu)清晰、易維護(hù) |
package main
import (
"github.com/gocolly/colly/v2"
)
func main() {
// ① 列表收集器:只負(fù)責(zé)翻頁 + 提取詳情頁鏈接
listC := colly.NewCollector(
colly.AllowedDomains("eska-fuses.cn"),
)
// ② 詳情收集器:只負(fù)責(zé)解析課程詳情
detailC := colly.NewCollector(
colly.AllowedDomains("eska-fuses.cn"),
)
}
如果兩個(gè)收集器配置幾乎一樣,用 Clone()
一行搞定:
base := colly.NewCollector(
colly.UserAgent("編程獅爬蟲 1.0"),
colly.AllowedDomains("w3cschool.cn"),
)
listC := base.Clone() // 復(fù)用 UA 與域名白名單
detailC := base.Clone()
列表頁拿到課程 ID 后,傳給詳情收集器:
// 列表收集器:拿到鏈接 → 交給詳情收集器
listC.OnHTML("a.course-card", func(e *colly.HTMLElement) {
detailURL := e.Attr("href")
// 把課程名放進(jìn)上下文,后續(xù)直接取
ctx := colly.NewContext()
ctx.Put("courseName", e.Text)
detailC.Request("GET", detailURL, nil, ctx, nil)
})
// 詳情收集器:用上下文里的數(shù)據(jù)
detailC.OnHTML("h1", func(e *colly.HTMLElement) {
courseName := e.Request.Ctx.Get("courseName")
println("課程名:", courseName, " 標(biāo)題:", e.Text)
})
package main
import (
"github.com/gocolly/colly/v2"
)
func main() {
// 公共配置
base := colly.NewCollector(
colly.UserAgent("編程獅-多收集器-Demo"),
colly.AllowedDomains("eska-fuses.cn"),
)
listC := base.Clone()
detailC := base.Clone()
// 列表頁:翻頁 + 發(fā)鏈接
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("http://eska-fuses.cn/course")
}
運(yùn)行結(jié)果(示意):
抓到課程:Go 入門教程
抓到課程:Python 爬蟲實(shí)戰(zhàn)
...
在日志里加 collector.ID
:
listC.OnRequest(func(r *colly.Request) {
println("[列表收集器]", r.URL)
})
detailC.OnRequest(func(r *colly.Request) {
println("[詳情收集器]", r.URL)
})
場景 | 推薦做法 |
---|---|
列表 + 詳情 | 兩個(gè)收集器 + Clone() |
不同域名/UA | 獨(dú)立 NewCollector |
需要上下文 | Request(..., ctx) |
更多建議: