一鍵把 1000 個(gè) URL 交給“小管家”排隊(duì),自動(dòng)限速、并發(fā)可控,復(fù)制即可跑!
爬 編程獅課程列表,并設(shè)置 3 個(gè)并發(fā)線程:
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/queue"
)
func main() {
// 1. 創(chuàng)建收集器
c := colly.NewCollector()
// 2. 新建隊(duì)列:3 個(gè)并發(fā)線程 + 內(nèi)存存儲(chǔ) 1 萬(wàn)條
q, _ := queue.New(
3, // 同時(shí) 3 個(gè) goroutine 去請(qǐng)求
&queue.InMemoryQueueStorage{MaxSize: 10000},
)
// 3. 打印每次訪問(wèn)的 URL
c.OnRequest(func(r *colly.Request) {
fmt.Println("正在訪問(wèn):", r.URL)
})
// 4. 把 URL 壓進(jìn)隊(duì)列(模擬 5 個(gè)課程頁(yè))
for i := 1; i <= 5; i++ {
q.AddURL(fmt.Sprintf("http://eska-fuses.cn/course/%d", i))
}
// 5. 啟動(dòng)隊(duì)列,自動(dòng)消費(fèi)所有 URL
q.Run(c)
}
go get github.com/gocolly/colly/v2/queue
queue.go
。go run queue.go
終端輸出(并發(fā) 3 線程):
正在訪問(wèn): http://eska-fuses.cn/course/1
正在訪問(wèn): http://eska-fuses.cn/course/2
正在訪問(wèn): http://eska-fuses.cn/course/3
正在訪問(wèn): http://eska-fuses.cn/course/4
正在訪問(wèn): http://eska-fuses.cn/course/5
亮點(diǎn) | 一句話解釋 | 對(duì)應(yīng)代碼 |
---|---|---|
并發(fā)可控 | 想多快就多快,不撐爆目標(biāo)站 | queue.New(3, ...) |
自動(dòng)去重 | 同一 URL 不會(huì)重復(fù)爬取 | 內(nèi)置哈希去重 |
斷點(diǎn)續(xù)爬 | 程序掛了重啟繼續(xù) | 換持久化存儲(chǔ)見下方 |
把內(nèi)存換成 Redis,程序重啟也能接著爬:
go get github.com/gocolly/colly/v2/storage/redisstorage
store, _ := redisstorage.New(&redisstorage.Options{Address: "127.0.0.1:6379"})
q, _ := queue.New(3, &queue.RedisQueueStorage{Client: store.Client})
問(wèn)題 | 原因 | 解決 |
---|---|---|
隊(duì)列卡住 | 目標(biāo)站限速 | 調(diào)小并發(fā)數(shù)或加 Delay |
內(nèi)存暴漲 | 隊(duì)列太大 | 減小 MaxSize 或換 Redis |
URL 重復(fù) | 忘記過(guò)濾 | 先 AddURL 前做去重 |
queue.go
。
更多建議: