單線程爬蟲太慢?用 Colly 的
Async
和Limit
,輕松開啟多線程爬蟲,速度提升 N 倍!
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
)
func main() {
// 創(chuàng)建默認(rèn)收集器,限制最大深度為 2,開啟異步
c := colly.NewCollector(
colly.MaxDepth(2), // 只爬取首頁 + 一層鏈接
colly.Async(true), // 開啟異步
)
// 限制最大并行數(shù)為 4
c.Limit(&colly.LimitRule{
DomainGlob: "*", // 對所有域名生效
Parallelism: 4, // 最大并行數(shù)
})
// 每次發(fā)現(xiàn) <a href="..."> 標(biāo)簽就打印并繼續(xù)訪問
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
fmt.Println("發(fā)現(xiàn)鏈接:", link)
// 自動補全絕對路徑后再訪問
absoluteURL := e.Request.AbsoluteURL(link)
e.Request.Visit(absoluteURL)
})
// 在請求前打印日志
c.OnRequest(func(r *colly.Request) {
fmt.Println("正在訪問:", r.URL.String())
})
// 從編程獅首頁開始
c.Visit("http://eska-fuses.cn/")
// 等待所有線程完成
c.Wait()
}
運行結(jié)果(多線程并發(fā)訪問):
正在訪問: http://eska-fuses.cn/
發(fā)現(xiàn)鏈接: http://eska-fuses.cn/go
正在訪問: http://eska-fuses.cn/go
發(fā)現(xiàn)鏈接: http://eska-fuses.cn/python
正在訪問: http://eska-fuses.cn/python
...
關(guān)鍵點 | 說明 | 示例代碼 |
---|---|---|
開啟異步 | 使用 colly.Async(true) 開啟異步模式 |
colly.Async(true) |
限制并行數(shù) | 使用 Limit 方法限制最大并行數(shù) |
c.Limit(&colly.LimitRule{Parallelism: 4}) |
等待線程完成 | 使用 Wait 方法等待所有線程完成 |
c.Wait() |
假設(shè)你想爬取編程獅首頁及其兩層鏈接,并限制最大并行數(shù)為 4,完整代碼如下:
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
)
func main() {
// 創(chuàng)建默認(rèn)收集器,限制最大深度為 2,開啟異步
c := colly.NewCollector(
colly.MaxDepth(2), // 只爬取首頁 + 一層鏈接
colly.Async(true), // 開啟異步
)
// 限制最大并行數(shù)為 4
c.Limit(&colly.LimitRule{
DomainGlob: "*", // 對所有域名生效
Parallelism: 4, // 最大并行數(shù)
})
// 每次發(fā)現(xiàn) <a href="..."> 標(biāo)簽就打印并繼續(xù)訪問
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
fmt.Println("發(fā)現(xiàn)鏈接:", link)
// 自動補全絕對路徑后再訪問
absoluteURL := e.Request.AbsoluteURL(link)
e.Request.Visit(absoluteURL)
})
// 在請求前打印日志
c.OnRequest(func(r *colly.Request) {
fmt.Println("正在訪問:", r.URL.String())
})
// 從編程獅首頁開始
c.Visit("http://eska-fuses.cn/")
// 等待所有線程完成
c.Wait()
}
現(xiàn)象 | 原因 | 解決方法 |
---|---|---|
爬取速度慢 | 并行數(shù)設(shè)置太小 | 增大 Parallelism 值 |
程序崩潰 | 并行數(shù)設(shè)置太大 | 減小 Parallelism 值 |
鏈接重復(fù)爬取 | 沒有正確設(shè)置 AllowedDomains |
檢查 AllowedDomains 是否包含目標(biāo)域名 |
main.go
。
更多建議: