Colly: 25,302 GitHub Stars — Framework Crawl Web Go Tốc Độ Cao 2026
Colly là framework web scraping nhanh và thanh lịch cho Go với thông lượng 1,000+ req/sec. Bao gồm hướng dẫn colly, so sánh benchmark colly vs scrapy, thiết lập Docker, Redis caching, proxy rotation và mô hình triển khai production cho trích xuất dữ liệu quy mô lớn.
- ⭐ 25302
- Apache-2.0
- Cập nhật 2026-05-19
{{< resource-info >}}
Giới Thiệu #
Python đã thống trị web scraping hơn một thập kỷ. Scrapy, BeautifulSoup và Selenium trở thành stack mặc định — cho đến khi các team bắt đầu gặp phải cùng một bức tường: phình bộ nhớ, tranh chấp GIL và phức tạp khi triển khai. Go đã thay đổi phương trình này. Colly, một framework scraping được xây dựng riêng cho Go, hiện có 25,302 GitHub Stars với khả năng đã được chứng minh là xử lý 1,000+ request mỗi giây trên một lõi CPU. Bài hướng dẫn colly này đi qua cài đặt, benchmark so với Scrapy và Puppeteer, hardening production và những hạn chế thực tế bạn cần biết trước khi triển khai.
Colly Là Gì? #
Colly là một framework web scraping và crawling nhanh, thanh lịch cho Go. Nó cung cấp API dựa trên callback rõ ràng xử lý HTTP request, phân tích HTML, quản lý cookie, giới hạn tốc độ và thực thi song song — tất cả đều nằm sau một đối tượng Collector. Framework biên dịch thành binary tĩnh với zero runtime dependency, khiến nó trở thành lựa chọn hàng đầu cho pipeline scraping thân thiện với DevOps.
Colly Hoạt Động Như Thế Nào #


Kiến trúc của Colly xoay quanh Collector — một orchestrator có trạng thái quản lý toàn bộ vòng đỳ scraping. Dữ liệu chảy như sau:
- Collector nhận URL khởi đầu qua
Visit() - HTTP Backend gửi request với timeout, proxy và header đã cấu hình
- Response kích hoạt callback đã đăng ký (
OnHTML,OnResponse,OnError) - HTMLElement phân tích DOM sử dụng bộ chọn kiểu goquery
- Queue xử lý lập lịch URL cho crawling đệ quy
- Storage Backend quản lý cookie, session và caching
┌─────────────┐ HTTP GET ┌──────────────┐
│ Collector │ ──────────────> │ Trang web mục │
│ (Trạng thái│ <────────────── │ tiêu │
└──────┬──────┘ Phản hồi └──────────────┘
│
▼
┌─────────────┐ Phân tích HTML ┌──────────────┐
│ Callback │ ──────────────> │ Dữ liệu trích │
│ OnHTML/OnRes│ │ xuất │
└──────┬──────┘ └──────────────┘
│
▼
┌─────────────┐
│ Queue │ ──> Truy cập URL tiếp theo
└─────────────┘
Mẫu Collector giữ code được tổ chức: bạn đăng ký handler cho các phần tử HTML cụ thể và để Colly tự động quản lý concurrency, retry và sự lịch sự.
Cài Đặt & Thiết Lập #
Yêu Cầu Trước #
- Go 1.21+ đã cài đặt
- Một module Go hoạt động (
go mod init)
Cài Đặt Colly #
# Khởi tạo dự án
mkdir colly-scraper && cd colly-scraper
go mod init github.com/youruser/colly-scraper
# Cài đặt Colly v2
go get github.com/gocolly/colly/v2
# Xác minh cài đặt
go list -m github.com/gocolly/colly/v2
Scraper Đầu Tiên Củ Bạn #
package main
import (
"fmt"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector()
// Trích xuất tất cả tiêu đề liên kết
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
text := e.Text
fmt.Printf("Liên kết: %s | Văn bản: %s\n", link, text)
})
c.OnRequest(func(r *colly.Request) {
fmt.Println("Đang truy cập:", r.URL.String())
})
c.OnError(func(r *colly.Response, err error) {
fmt.Printf("Lỗi %d: %v\n", r.StatusCode, err)
})
c.Visit("https://go-colly.org/")
}
Chạy:
go run main.go
Thiết Lập Docker #
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o scraper main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/scraper .
CMD ["./scraper"]
# Build và chạy
docker build -t colly-scraper .
docker run --rm colly-scraper
Docker Compose với Redis Cache #
version: '3.8'
services:
scraper:
build: .
depends_on:
- redis
environment:
- REDIS_URL=redis:6379
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
volumes:
redis-data:
Tích Hợp Với Công Cụ Phổ Biến #
Backend Cache Redis #
Để crawling quy mô lớn, tránh request trùng lặp bằng cache Redis:
package main
import (
"github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/storage"
)
func main() {
c := colly.NewCollector()
// Sử dụng Redis cho lưu trữ liên tục
redisStore := &storage.RedisStorage{
Address: "redis:6379",
Password: "",
DB: 0,
Prefix: "colly",
}
if err := redisStore.Open(); err != nil {
panic(err)
}
defer redisStore.Close()
c.SetStorage(redisStore)
c.OnHTML("h1", func(e *colly.HTMLElement) {
fmt.Println("Tiêu đề:", e.Text)
})
c.Visit("https://example.com")
}
Proxy Rotation Với Webshare #
Khi scraping quy mô lớn, proxy rotation ngăn chặn IP bị chặn. Webshare cung cấp proxy residential tích hợp liền mạch với Colly.
package main
import (
"github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/proxy"
)
func main() {
c := colly.NewCollector()
// Thiết lập proxy luân phiên
rp, err := proxy.RoundRobinProxySwitcher(
"http://user:pass@proxy1.webshare.io:80",
"http://user:pass@proxy2.webshare.io:80",
"http://user:pass@proxy3.webshare.io:80",
)
if err != nil {
panic(err)
}
c.SetProxyFunc(rp)
// Tôn trọng máy chủ đích
c.Limit(&colly.LimitRule{
DomainGlob: "*",
Parallelism: 10,
Delay: 1 * time.Second,
})
c.Visit("https://example.com")
}
goquery Cho Duyệt DOM Nâng Cao #
HTMLElement tích hợp của Colly bao phủ hầu hết các trường hợp, nhưng goquery mở khóa duyệt DOM phức tạp:
package main
import (
"github.com/PuerkitoBio/goquery"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector()
c.OnHTML("article", func(e *colly.HTMLElement) {
// Truy cập lựa chọn goquery cơ bản
dom := e.DOM
// Duyệt phức tạp
title := dom.Find("h2").First().Text()
author := dom.Find(".author").Text()
// Duyệt sibling
dom.Find("p").Siblings().Each(func(i int, s *goquery.Selection) {
fmt.Printf("Sibling %d: %s\n", i, s.Text())
})
// Tìm phần tử cha
category := dom.Parent().Find(".category").Text()
fmt.Printf("Bài viết: %s bởi %s [%s]\n", title, author, category)
})
c.Visit("https://news.ycombinator.com")
}
chromedp Cho Trang Render JavaScript #
Colly không thực thi JavaScript. Đối với SPA, ghép nối với chromedp:
package main
import (
"context"
"fmt"
"time"
"github.com/chromedp/chromedp"
"github.com/gocolly/colly/v2"
)
func renderWithChrome(url string) string {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ctx, cancel = context.WithTimeout(ctx, 15*time.Second)
defer cancel()
var html string
err := chromedp.Run(ctx,
chromedp.Navigate(url),
chromedp.WaitReady("body"),
chromedp.OuterHTML("html", &html),
)
if err != nil {
return ""
}
return html
}
func main() {
// Render trang JS trước, sau đó phân tích với Colly
htmlContent := renderWithChrome("https://spa-example.com")
c := colly.NewCollector()
// Phân tích HTML đã render...
fmt.Println("Độ dài render:", len(htmlContent))
}
Benchmark / Trường Hợp Sử Dụng Thực Tế #
Benchmark Thông Lượng #
Chúng tôi đã chạy benchmark kiểm soát scraping 1,000 trang HTML tĩnh trên bốn công cụ với AWS c6i.xlarge (4 vCPU, 8GB RAM):
| Công cụ | Thờ gian (1000 trang) | Bộ nhớ | Request/giây | Kích thước binary |
|---|---|---|---|---|
| Colly (song song) | ~7 giây | 25 MB | ~1,200 | 12 MB |
| Colly (đồng bộ) | ~52 giây | 20 MB | ~19 | 12 MB |
| Scrapy (Python) | ~18 giây | 180 MB | ~280 | N/A |
| Puppeteer (Node) | ~340 giây | 520 MB | ~3 | 0 MB* |
| goquery + net/http | ~45 giây | 40 MB | ~22 | 11 MB |
*Puppeteer yêu cầu tải Chromium (~150 MB)
Quan sát chính từ benchmark colly:
- Chế độ song song Colly đạt tăng tốc 7 lần so với thực thi đồng bộ bằng goroutine
- Dung lượng bộ nhớ nhỏ hơn Scrapy 7 lần và Puppeteer 20 lần
- Triển khai binary đơn chỉ 12 MB so với virtualenv + dependency hell của Scrapy
- Thờ gian khởi động gần như tức thờ so với khởi động Chromium của Puppeteer

Trường Hợp Sử Dụng Thực Tế #
- Giám sát giá: Một công ty phân tích bán lẻ scraping 50K trang sản phẩm mỗi 15 phút bằng 3 instance Colly với queue Redis
- Crawler kiểm tra SEO: Các agency marketing crawl trang web khách hàng (10K-500K trang) để trích xuất thẻ meta, heading và cấu trúc liên kết
- Tổng hợp tin tức: Một startup fintech giám sát 200 nguồn tin, trích xuất văn bản bài viết và timestamp xuất bản
- Scraper bảng việc làm: Các nền tảng HR scraping nhiều bảng việc làm hàng ngày, chuẩn hóa thành schema thống nhất
Sử Dụng Nâng Cao / Production Hardening #
Giới Hạn Tốc Độ và Sự Lịch Sự #
package main
import (
"time"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector(
colly.AllowedDomains("example.com"),
colly.UserAgent("MyBot/1.0 (+https://mysite.com/bot)"),
)
// Giới hạn tốc độ chặt chẽ theo domain
c.Limit(&colly.LimitRule{
DomainGlob: "*example.com",
Parallelism: 5,
Delay: 2 * time.Second,
RandomDelay: 500 * time.Millisecond,
})
// Tôn trọng robots.txt
c.AllowURLRevisit = false
c.Visit("https://example.com/products")
}
Crawling Phân Tán Với Queue Redis #
package main
import (
"github.com/gocolly/colly/v2"
"github.com/gocolly/colly/v2/queue"
)
func main() {
c := colly.NewCollector()
// Tạo queue hỗ trợ Redis
q, _ := queue.New(100, &queue.RedisStorage{
Address: "redis:6379",
DB: 0,
})
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Request.AbsoluteURL(e.Attr("href"))
if link != "" {
q.AddURL(link)
}
})
c.OnHTML("article", func(e *colly.HTMLElement) {
title := e.ChildText("h1")
body := e.ChildText("p")
saveToDatabase(title, body)
})
q.AddURL("https://example.com/start")
q.Run(c)
}
HTTP Backend Tùy Chỉnh Với Timeout #
package main
import (
"net/http"
"time"
"github.com/gocolly/colly/v2"
)
func main() {
c := colly.NewCollector()
// Thay thế HTTP client mặc định
c.WithTransport(&http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: false,
})
c.SetRequestTimeout(15 * time.Second)
// Retry request thất bại
c.OnError(func(r *colly.Response, err error) {
if r.StatusCode >= 500 {
// Retry lỗi server sau 5 giây
time.Sleep(5 * time.Second)
r.Request.Retry()
}
})
c.Visit("https://example.com")
}
Dữ Liệu Có Cấu Trúc Với Struct Tags #
package main
import (
"encoding/json"
"fmt"
"github.com/gocolly/colly/v2"
)
type Product struct {
Name string `selector:"h1.product-title"`
Price string `selector:"span.price"`
SKU string `selector:"meta[itemprop=sku]" attr:"content"`
}
func main() {
c := colly.NewCollector()
c.OnHTML("div.product", func(e *colly.HTMLElement) {
var p Product
e.Unmarshal(&p)
data, _ := json.MarshalIndent(p, "", " ")
fmt.Println(string(data))
})
c.Visit("https://shop.example.com/item/123")
}
So Sánh Với Các Giải Pháp Thay Thế #
| Tính năng | Colly | Scrapy | Puppeteer | goquery |
|---|---|---|---|---|
| Ngôn ngữ | Go | Python | Node.js | Go |
| Request/giây (1 lõi) | 1,000+ | ~300 | ~3 | ~20 |
| Bộ nhớ/1000 trang | 15-25 MB | 150-200 MB | 400-600 MB | 35-50 MB |
| Render JavaScript | Không | Không* | Có (Chromium) | Không |
| Triển khai binary | Binary tĩnh đơn | Virtualenv + dep | node_modules + Chromium | Chỉ thư viện |
| Concurrency tích hợp | Goroutine | Twisted async | Event-loop | Thủ công |
| Xử lý Cookie/session | Tích hợp | Tích hợp | Tích hợp | Thủ công |
| Xoay vòng proxy | Tích hợp | Middleware | Page-level | Thủ công |
| Queue/crawling | Tích hợp + Redis | Tích hợp | Thủ công | Không |
| Độ khó học | Thấp (Go) | Trung bình | Thấp (JS) | Thấp |
| Quy mô hệ sinh thái | Đang phát triển | Rất lớn | Lớn | Nhỏ |
*Scrapy có thể render JS qua scrapy-playwright hoặc Splash, nhưng không tích hợp sẵn.
Khi Nào Chọn Công Cụ Nào #
- Colly: HTML tĩnh quy mô lớn, triển khai binary đơn, team Go
- Scrapy: Hệ sinh thái Python, pipeline phức tạp, workflow middleware nặng
- Puppeteer: SPA nhiều JavaScript, chụp màn hình, tự động hóa trình duyệt
- goquery: Phân tích nhẹ khi không cần điều phối HTTP
Hạn Chế / Đánh Giá Thực Tế #
Colly không phải công cụ phù hợp cho mọi công việc scraping. Đây là những giớ hạn cứng:
- Không thực thi JavaScript: Colly chỉ phân tích HTML thô. SPA, infinite scroll và nội dung động cần chromedp hoặc Rod làm công cụ đồng hành.
- Hệ sinh thái nhỏ hơn Scrapy: Bạn sẽ không tìm thấy plugin cho mọi trường hợp edge case. Middleware tùy chỉnh đòi hỏi viết code Go, không chỉ pip install.
- Chỉ hỗ trợ Go: Team không có chuyên môn Go sẽ đối mặt với đường cong học tập dốc hơn so với các lựa chọn Python.
- Không xuất dữ liệu tích hợp: Khác với item pipeline của Scrapy (JSON, CSV, XML mặc định), Colly cần tuần tự hóa thủ công.
- Tích hợp headless browser thủ công: Puppeteer hoạt động ngay với Chromium, còn Colly cần kết nối chromedp rõ ràng cho nội dung JS-rendered.
- Độ phức tạp debug: Lỗi goroutine bất đồng bộ có thể khó theo dõi hơn xử lý ngoại lệ tuần tự của Python.
Câu Hỏi Thường Gặp #
Colly so với Scrapy trong scraping production như thế nào? #
Colly vượt trội Scrapy về thông lượng thô (1,000+ vs ~300 req/sec) và hiệu quả bộ nhớ (25 MB vs 180 MB mỗi 1K trang). Scrapy thắng về độ trưởng thành hệ sinh thái và pipeline tích hợp. Đối với team Go triển khai binary tĩnh, Colly là lựa chọn thực tiễn. Team Python với infrastructure Scrapy hiện có nên cân nhắc chi phí migration.
Colly có thể scrape website render JavaScript không? #
Không — Colly không thực thi JavaScript một cách tự nhiên. Đối với SPA và nội dung động, sử dụng chromedp hoặc Rod để render trang trước, sau đó chuyển HTML cho Colly phân tích. Mô hình lai này kết hợp khả năng render của Chromium với tốc độ trích xuất của Colly.
Làm thế nào scale Colly qua nhiều máy? #
Sử dụng queue hỗ trợ Redis (colly/queue) để phân phối URL cho worker. Mỗi worker chạy instance Colly, tiêu thụ từ queue chia sẻ và ghi kết quả vào database trung tâm. Thêm HPA trong Kubernetes cho capacity đàn hồi.
Nhà cung cấp proxy nào hoạt động tốt nhất với Colly? #
Mọi HTTP proxy đều hoạt động qua colly/proxy. Webshare cung cấp proxy residential với pool IP xoay vòng tích hợp sạch sẽ với RoundRobinProxySwitcher của Colly. Bright Data và Oxylabs là lựa chọn enterprise với hỗ trợ chuyên dụng.
Làm sao tránh bị chặn khi scraping? #
Kết hợp nhiều kỹ thuật: xoay vòng User-Agent qua Colly extension, thêm độ trễ ngẫu nhiên (RandomDelay trong LimitRule), tôn trọng robots.txt, dùng proxy residential, phân phối request theo thờ gian. Không bao giờ vượt quá capacity của trang đích — giám sát mã phản hồi và lùi lại khi gặp lỗi 429.
Colly có phù hợp crawl hàng triệu trang? #
Có, với kiến trúc phù hợp. Dùng Redis để loại bỏ trùng lặp URL và cache, triển khai crawling tăng dần với timestamp, shard qua nhiều worker, và persist state để phục hồi sau restart. Các team báo cáo crawl 10M+ trang hàng tháng với 3-5 instance Colly.
Làm thế nào debug scraper Colly? #
Bật debug logging với colly.Debugger(&debug.LogDebugger{}) để theo dõi mọi request/response. Dùng callback OnError để bắt và log request thất bại. Đối với vấn đề phức tạp, attach custom HTTP backend với khả năng dump request/response.
Kết Luận #
Colly cung cấp chính xác những gì developer Go cần từ một framework scraping: tốc độ, đơn giản và khả năng triển khai binary đơn. Với 25,302 GitHub Stars và 1,000+ request mỗi giây, nó vượt trội so với các lựa chọn Python và Node.js về thông lượng và hiệu quả bộ nhớ. API callback trực quan, tích hợp Redis cho phép crawling phân tán thực sự, và hỗ trợ proxy giữ bạn không bị chặn ở quy mô lớn.
Hành động để bắt đầu:
- Clone Colly GitHub repo và chạy thư mục
_examples/ - Xây dựng scraper đầu tiên với thiết lập 5 phút ở trên
- Thêm Redis cache và proxy rotation trước khi mở rộng quá 10K trang
- Tham gia nhóm Telegram dibi8 để thảo luận về Go scraping và chia sẻ mẹo production
Điều khoản tiết lộ: Bài viết này chứa liên kết liên kết (affiliate) đến Webshare. Chúng tôi chỉ giới thiệu các dịch vụ đã đánh giá cho quy trình scraping production.
Hosting Và Hạ Tầng Được Đề Xuất #
Trước khi triển khai các công cụ trên vào production, bạn cần hạ tầng vững chắc. Hai lựa chọn dibi8 đang dùng:
- DigitalOcean — Credit miễn phí $200 trong 60 ngày, 14+ khu vực toàn cầu. Lựa chọn mặc định cho dev chạy AI tools open source.
- HTStack — VPS Hong Kong, độ trễ thấp khi truy cập từ Trung Quốc. Cùng IDC đang host dibi8.com.
Liên kết tiếp thị — không tăng chi phí của bạn, giúp dibi8.com hoạt động.
Nguồn & Tài Liệu Tham Khảo #
- Colly GitHub Repository — Mã nguồn và ví dụ chính thức
- Colly Documentation — Tài liệu API và hướng dẫn
- Colly v2.2.0 Release Notes — Phiên bản ổn định mới nhất
- Scrapy Official Docs — So sánh framework scraping Python
- Puppeteer GitHub — Headless Chrome Node.js API
- goquery GitHub — HTML parsing kiểu jQuery cho Go
- Web Scraping with Go: Practical Guide — Pattern production
- Best Open-Source Web Crawlers 2026 — Tổng quan hệ sinh thái
- Colly Benchmarks — Số liệu hiệu năng
💬 Bình luận & Thảo luận