Chỉ cần tìm “Colly”, từ miêu tả đầu tiên bạn sẽ luôn thấy là: nhanh. Go crawler nhanh, nhanh vì nó biên dịch được, nhanh vì không bị trình duyệt làm vướng. Nhưng hầu như chẳng ai đưa ra con số cụ thể.
Vậy nên tôi không còn tin vào lời quảng cáo suông nữa. Tôi dựng một site fixture nhỏ, compile Colly để chạy với nó, rồi xem thư viện này thực sự làm được gì — khả năng lấy dữ liệu trên trang thật, cách nó xử lý một request lỗi, và một lượt crawl bị giới hạn độ sâu có thể đi xa đến đâu. Tóm tắt ngắn gọn trước khi vào số liệu: phần trích xuất tĩnh đạt recall đầy đủ, lỗi 500 đi đúng nơi cần đến, và một lượt crawl bị giới hạn depth đã đi tới 17 trang chỉ từ một file nhị phân tĩnh, không cần gắn browser. Thư viện cũng trả về 0 rất sạch trên mọi nội dung được render bằng JavaScript — đúng phần mà phe “nhanh” thường hay lờ đi.
Colly thực chất là gì, và không phải là gì

Colly tự giới thiệu là một “elegant scraper and crawler framework for Golang”, và chỉ một câu đó đã nói lên nhiều hơn bạn nghĩ. Đây là một thư viện Go — hiện có khoảng ~25.4k stars tính đến 2026-07-09 trên gocolly/colly, được cấp phép Apache-2.0. Nó không phải công cụ dòng lệnh bạn tải về rồi nhập URL là chạy. Bạn viết Go, import package, gắn vài callback, rồi biên dịch thành một executable duy nhất.
Mô hình hoạt động của nó là event-driven, và điều này khiến nhiều người quen kiểu request rồi parse bị “khựng” lại. Bạn không lặp qua response rồi bóc tách từng field theo dòng. Bạn gắn handler vào một Collector rồi để thư viện tự bắn callback khi nó đi qua các trang. OnHTML sẽ chạy code trích xuất của bạn mỗi khi gặp selector CSS khớp. OnResponse đưa cho bạn raw response body, rất hữu ích khi payload là JSON chứ không phải HTML. OnError bắt những request thất bại. Cơ chế crawl cũng tương tự: trong handler xử lý link, bạn gọi Visit() trên các URL tìm thấy, Colly sẽ xếp chúng vào hàng đợi, còn MaxDepth quyết định nó được đi xa đến đâu. Callback, hàng đợi visit, giới hạn độ sâu, binary tĩnh đã compile. Không interpreter, không runtime, không headless Chrome nằm ì trong bộ nhớ.
Mô hình callback, và vì sao nó làm thay đổi cảm giác khi trích xuất dữ liệu
Callback chính là “tính cách” của công cụ này, nên đáng để nói kỹ hơn. Ba callback dưới đây đã xử lý toàn bộ các bài test của tôi.
OnHTML(selector, handler) là cái bạn sẽ dùng nhiều nhất. Gắn nó vào .product hoặc article p, rồi Colly sẽ gọi handler của bạn một lần cho mỗi phần tử khớp trong lúc parse DOM. Đây là nơi trích xuất có cấu trúc diễn ra, và nó đọc rất gọn — bạn mô tả cái mình muốn, chứ không phải vòng lặp để lấy nó.
OnResponse(handler) nằm thấp hơn một tầng và cho bạn raw bytes trực tiếp từ mạng. Khi mục tiêu trả JSON thay vì markup, bạn không cần đụng DOM — bạn tự unmarshal body. Chỉ riêng callback này đã đủ để Colly xử lý một JSON API trong lần chạy của tôi mà không cần parse lấy một mẩu HTML nào.
OnError(handler) là callback mà ai cũng quên cho đến khi scraper chết lúc 3 giờ sáng. Nó được gọi khi request thất bại và đưa response cho bạn, để bạn đọc status code rồi quyết định bước tiếp theo. Một crawler âm thầm nuốt lỗi còn tệ hơn một crawler hỏng toang ra mặt; Colly không làm cả hai, và điều đó quan trọng hơn vẻ ngoài của nó nhiều, nhất là khi job chạy không người giám sát.
Có thêm hai tính năng nữa nằm phía trên các callback đó và rất quan trọng trong vận hành. MaxDepth giới hạn độ sâu crawl, nên collector đi theo link sẽ dừng lại sau hai bước nhảy thay vì lang thang khắp web. Và đầu ra build là một binary Go tĩnh duy nhất — compile một lần, có một file, không phụ thuộc runtime, có thể thả lên server hoặc đưa vào CI rồi chạy luôn. Nếu bạn từng mất nguyên một buổi chiều vì Python virtualenv trên một máy mới tinh, kiểu triển khai này trông như một lợi thế chứ không phải chi tiết phụ.
Thiết lập — thứ mà ít ai nói đến trong Go toolchain
Phần phụ thuộc khá ngắn, nhưng có một điểm vướng thực sự, nên tôi nói luôn trước khi bạn cài bất cứ thứ gì. Máy tôi test ban đầu hoàn toàn chưa có Go, mà Colly là thư viện Go, nên bước đầu tiên là cài toolchain lên máy — tôi đã cài Go 1.26.5 qua Homebrew. Nếu team bạn chưa quen Go, đó mới là ma sát thật sự. Không phải thư viện. Mà là môi trường ngôn ngữ bắt buộc phải có trước khi một dòng code nào được compile.
Khi đã có Go, việc kéo Colly về rất gọn. go get github.com/gocolly/colly/v2 trả về v2.3.0 rất êm — không browser, không headless gì cả, cuối cùng chỉ là một binary được biên dịch. So với các scraper Python phải cài parser rồi gãy ngay ở lần fetch đầu tiên vì thiếu một chuỗi extras nào đó, cảm giác này thật sự dễ chịu. Mà “dễ chịu” ở đây là một lời khen.
Có một ghi chú chính xác cần nói rõ, vì nếu bạn tự đi tra rất dễ bị rối. Module mới nhất trên Go proxy là v2.3.0, phát hành vào tháng 12 năm 2025. Còn release được tag mới nhất trên GitHub là v2.2.0, từ tháng 3 năm 2025. Vì vậy code tôi test — v2.3.0 — mới hơn những gì trang Releases trên repository hiển thị. Đây là một đặc điểm lệch pha giữa Go modules và GitHub tags theo thời gian, chứ không phải dấu hiệu có lỗi gì. Chỉ cần đừng ngạc nhiên khi go get và trang Releases cho bạn hai con số khác nhau.
Thực chiến — những con số đằng sau chữ “nhanh”
Tôi chạy Colly trên một fixture server tự dựng bằng httptest của Go, cộng thêm hai site demo công khai, để hành vi có thể tái lập chứ không chỉ là câu chuyện tôi kể. Kết quả như sau.

| Bài test | Mục tiêu | Kết quả |
|---|---|---|
| Catalog tĩnh + phân trang | fixture cục bộ | 12/12 sản phẩm, recall 1.0 |
| Trích xuất bài viết | fixture cục bộ | tiêu đề + 3/3 đoạn |
| Dynamic JSON API | fixture cục bộ | 8/8 mục qua OnResponse, recall 1.0 |
| Xử lý HTTP 500 | fixture cục bộ | chuyển sang OnError, status 500 |
Crawl graph (MaxDepth 2) | fixture cục bộ | 17 trang |
| Books to Scrape | demo công khai | 20 sản phẩm |
| Trang động (không JS) | fixture cục bộ | 0 card (đúng như kỳ vọng) |
| Quotes JS (không render) | demo công khai | 0 (đúng như kỳ vọng) |

Đọc từ trên xuống dưới, bức tranh khá rõ. Trích xuất tĩnh rất sạch — 12/12 sản phẩm từ catalog, cả 3/3 đoạn từ bài viết, tất cả đều được điều khiển bởi selector OnHTML. Bài test API JSON không hề mở parser HTML: OnResponse đưa body về, tôi tự unmarshal, và 8/8 item đều xuất hiện. Bài test 500 là phần tôi tin nhất, vì nó là ranh giới giữa một crawler bạn có thể để chạy qua đêm và một crawler không thể — Colly đẩy lỗi sang OnError và hiển thị status rõ ràng, không crash, cũng không nuốt mất lỗi. Trên demo công khai Books to Scrape, nó lấy được 20 sản phẩm mà không cần xử lý đặc biệt nào.
Kết quả crawl mới là điểm nhấn, và tôi muốn nói thật chính xác. Một collector MaxDepth(2), theo các link và chuyển chúng sang URL tuyệt đối, đã đi tới 17 trang trong graph fixture của tôi. Đó là câu “fast Go crawler” cuối cùng cũng được gắn với con số trang thật thay vì cảm tính. Nhưng cần đọc kỹ cách diễn đạt — 17 trang trong một lượt crawl depth-2. Con số depth ở đây là bộ đếm trong harness test của tôi, mô tả cách tôi cấu hình chạy; tôi không khẳng định Colly nội bộ đảm bảo “chính xác depth 2, không đi thêm một bước nào nữa” như một cam kết. Phát biểu trung thực, có thể kiểm chứng là: khi giới hạn depth ở 2, crawl đã đi qua graph và chạm tới 17 trang.

Giờ đến giới hạn, là lúc những bài viết kiểu “nó nhanh lắm” thường im bặt. Colly không chạy JavaScript. Tôi đưa nó vào một fixture được render bằng JavaScript và nhận lại 0 card; tôi đem thử với trang Quotes to Scrape JS công khai và lại nhận 0. Đó không phải bug, cũng không phải điểm trừ. Colly là HTTP crawler — nó tải và parse HTML, nhưng không khởi động browser để chạy script phía client. Giống Scrapy và các HTTP-first crawler khác, nếu nội dung bạn cần chỉ xuất hiện sau khi JavaScript chạy xong, Colly sẽ luôn trả về kết quả rỗng, và tốc độ thô không thể thay đổi thực tế đó. Muốn làm được thì phải ghép thêm renderer, hoặc chọn công cụ đã có sẵn browser.
Tôi cũng nói rõ luôn những gì mình không test, để không ai kéo kết quả của tôi đi xa hơn bằng chứng cho phép. Tôi không đẩy async collector, cấu hình rate limiting và politeness, xoay proxy, hay các backend queue và storage. Colly có các phần đó. Tôi chỉ chạy lõi trích xuất và crawl, không phải lớp hạ tầng để scale. README quảng cáo throughput hơn một nghìn request mỗi giây trên một core, nhưng đó là con số của chính dự án — tôi đo page count và recall, không đo throughput, nên khi tôi nói “nhanh” thì ý tôi là đường xử lý trích xuất bằng Go đã compile mà tôi thực sự kiểm tra, chứ không phải một benchmark so sánh với Scrapy mà tôi chưa chạy.
Ưu và nhược điểm
Ưu điểm:
- Recall đầy đủ trên phần trích xuất tĩnh — 12/12 sản phẩm catalog và 3/3 đoạn bài viết qua
OnHTML. - Xử lý JSON gọn qua
OnResponse, không cần parse DOM — 8/8 item từ API. - Chuyển lỗi đúng cách — status 500 đi vào
OnErrorvà được hiển thị rõ ràng, không crash. - Một lượt crawl có giới hạn độ sâu đã đi tới 17 trang từ một collector duy nhất.
- Một binary Go tĩnh, không phụ thuộc runtime — rất đẹp cho triển khai và vận hành.
- Giấy phép Apache-2.0 khá thoáng.
Nhược điểm:
- Không chạy JavaScript — nội dung render phía client trả về 0, hết.
- Cần Go toolchain; đội ngũ chưa dùng Go sẽ phải trả chi phí thiết lập trước khi viết scraper.
- Module mới nhất (
v2.3.0) đi trước release tag mới nhất trên GitHub (v2.2.0), dễ làm người đọc trang Releases bối rối. - Output là do chính code của bạn tạo ra — Colly đưa callback, chứ không cho sẵn dataset hay trình export feed như Scrapy.
- Async, rate limiting, proxy và queue backend có tồn tại nhưng không được test ở đây; “nhanh” trong bài này là đường trích xuất tôi đo được, không phải số throughput đối đầu trực tiếp.
Colly phù hợp với ai — và ai nên bỏ qua

Colly hợp với bạn nếu bạn đã viết Go và đang crawl các site dựa trên HTML hoặc JSON với tốc độ cao. Nếu định nghĩa của bạn về một triển khai gọn là chỉ cần copy một binary lên máy rồi chạy — không interpreter, không virtualenv, không roulette phụ thuộc — thì công cụ này được sinh ra đúng cho kiểu làm việc đó. Mô hình callback chứng minh giá trị ngay khi việc trích xuất không còn đơn giản: OnHTML cho cấu trúc, OnResponse cho payload thô, OnError cho những lỗi nếu không gắn vào thì bạn sẽ chẳng bao giờ thấy. Với mục tiêu tĩnh hoặc API-backed, chạy theo lịch từ CI, đây là một lựa chọn mạnh và ít gây phiền toái.
Bạn nên bỏ qua, hoặc ít nhất phải ghép thêm một công cụ khác, khi mục tiêu phụ thuộc nặng vào JavaScript. Colly trả về 0 trên mọi trang được render phía client mà tôi thử, và đó là thiết kế chứ không phải một tuỳ chọn có thể bật/tắt. Cũng nên bỏ qua nếu đội của bạn không đụng Go và bạn không muốn dựng toolchain chỉ để scrape vài website — cam kết với ngôn ngữ là có thật, và bạn phải tự duy trì nó. Và nếu bạn muốn dữ liệu có cấu trúc được trả sẵn cho mình thay vì phải parse bằng code tự viết, thì toàn bộ callback của Colly sẽ đẩy phần việc đó về phía bạn.
Lựa chọn thay thế — khi nào API scraping AI được quản lý sẵn phù hợp hơn
Colly là một thư viện mã nguồn mở miễn phí, bạn tự compile và tự chạy. Bạn sở hữu code Go, callback, logic crawl, và cả máy chủ chạy nó — đổi lại, bạn không phải trả tiền trên mỗi request và giữ toàn bộ vận hành trong nhà. Với một đội Go, đó là câu trả lời hoàn toàn hợp lý, và kiểu triển khai một binary thật sự rất dễ chịu.
Hai điểm Colly dừng lại cũng chính là hai điểm đáng để so với giải pháp khác. Thứ nhất, JavaScript — Colly không render nó, nên mọi thứ chỉ xuất hiện sau khi client-side chạy xong đều nằm ngoài khả năng của nó, trừ khi bạn ghép thêm browser. Thứ hai, cấu trúc đầu ra — Colly đưa callback cho bạn và để bạn tự tạo dữ liệu sạch. Một API scraping AI được quản lý sẵn sẽ xử lý hai phần đó theo cách khác. Bộ công cụ dành cho developer của Thunderbit xử lý render JavaScript và trả dữ liệu có cấu trúc ngay phía server. POST /distill biến một trang thành Markdown sạch, sẵn sàng cho LLM, với nội dung động và anti-bot đã được xử lý hộ. POST /extract trả JSON có cấu trúc theo JSON Schema bạn định nghĩa, với renderMode có thể tăng lên full browser rendering khi trang cần. Thunderbit còn có MCP server cho AI agents và coding assistants — thunderbit_suggest_fields là miễn phí, nên bạn có thể dò xem một trang có những field gì trước khi quyết định — và cả CLI để chạy qua terminal, CI, hoặc cron bằng npx @thunderbit/thunderbit-cli.
Dùng thử Thunderbit để trích xuất dữ liệu web
Sự đánh đổi không phải là tốt hơn hay tệ hơn. Mà là công việc nằm ở đâu. Với Colly, bạn giữ phần render (không có), parsing và bảo trì trong chính binary đã compile của mình, không tốn phí theo từng lần gọi, và tự chăm nó khi website thay đổi cấu trúc. Với API được quản lý, bạn giao luôn phần render JavaScript, anti-bot và output có cấu trúc, rồi trả tiền theo lượt gọi để đổi lấy sự tiện đó. Nếu mục tiêu của bạn nhỏ, native Go, dựa trên HTML hoặc JSON và bạn sẵn sàng sở hữu, duy trì nó, Colly thắng về kiểm soát và tốc độ. Còn nếu trang nặng JavaScript, hoặc đơn giản là bạn muốn nhận JSON theo schema thay vì viết thêm một callback nữa, thì đó là trường hợp nên đi theo hướng managed. Nếu bạn muốn nhìn toàn cảnh rộng hơn, các bài tổng hợp về best web scraping tools và best web scraping GitHub projects sẽ giúp bạn thấy vị trí của một thư viện như Colly bên cạnh các lựa chọn dựa trên browser và dịch vụ được quản lý.
Kết luận
Có nên dùng Colly không? Có — nếu bạn viết Go và đang crawl HTML hoặc JSON với tốc độ cao, nó làm đúng điều mà danh tiếng “fast crawler” hứa hẹn, và giờ đã có con số chứng minh phía sau. Recall đầy đủ trên trích xuất tĩnh. JSON sạch qua OnResponse. Một lỗi 500 đi đúng vào OnError thay vì biến mất. Một lượt crawl depth-2 đi tới 17 trang. Tất cả được biên dịch thành một binary tĩnh duy nhất, không phụ thuộc runtime, đây gần như là câu chuyện triển khai dễ chịu nhất trong cả nhóm công cụ này.
Nhưng hãy đặt kỳ vọng cho đúng. Nó không render JavaScript — mọi trang client-side trong lần test của tôi đều trả 0, và đó là giới hạn cố định chứ không phải một cài đặt bạn quên bật. Nó cần Go toolchain, nên đội không dùng Go sẽ phải trả phí thiết lập ban đầu. Module bạn cài (v2.3.0) mới hơn release tag mới nhất trên GitHub (v2.2.0), nên đừng hoảng khi hai trang hiển thị khác nhau. Và “nhanh” ở đây là đường xử lý trích xuất tôi đã đo, chứ không phải một benchmark throughput tôi chưa chạy. Trong những ranh giới đó, Colly là một Go crawler nhanh, ổn định, thực sự dễ triển khai — và nó xứng đáng với danh tiếng đó ngay khi bạn ngừng bắt nó chạy JavaScript.
Dùng thử Thunderbit để trích xuất dữ liệu web Get Started Free
Câu hỏi thường gặp
Colly có thật sự nhanh không, và có con số nào chứng minh không? Nó nhanh theo nghĩa quan trọng nhất đối với đường xử lý lõi mà tôi đo được: Go đã compile, recall đầy đủ trên trích xuất tĩnh (12/12 sản phẩm catalog), xử lý JSON sạch, và một lượt crawl depth-2 đi tới 17 trang — tất cả từ một binary tĩnh duy nhất. Nhưng tôi không chạy benchmark throughput với Scrapy, nên hãy hiểu “nhanh” ở đây là hành vi trích xuất đã đo, không phải điểm tốc độ đối đầu trực tiếp.
Colly có scrape được trang render bằng JavaScript không? Không. Colly là HTTP crawler — nó tải và parse HTML nhưng không bao giờ chạy browser. Fixture render bằng JavaScript trả về 0 card, và trang Quotes JS công khai cũng trả về 0. Nếu cần nội dung phía client, bạn phải ghép Colly với renderer hoặc dùng công cụ có sẵn browser rendering.
Tôi có cần biết Go để dùng Colly không?
Có. Colly là một thư viện Go, không phải CLI độc lập — bạn import nó, đăng ký callback (OnHTML, OnResponse, OnError), rồi compile. Máy tôi test ban đầu không có Go, nên việc thiết lập bắt đầu bằng cài toolchain (1.26.5). Nếu team bạn chưa làm việc với Go, đó mới là chi phí thiết lập thực sự.
Vì sao phiên bản tôi cài không khớp với release mới nhất trên GitHub của Colly?
Vì Go module và GitHub release tag đã lệch nhau theo thời gian. Module mới nhất trên Go proxy là v2.3.0 (tháng 12 năm 2025), trong khi tag release mới nhất trên GitHub là v2.2.0 (tháng 3 năm 2025). Tôi đã test v2.3.0. Đây là chuyện modules và tags lệch nhịp, không phải cài đặt lỗi.
Colly có miễn phí cho mục đích thương mại không? Có, nó dùng giấy phép Apache-2.0, khá thoáng và thân thiện với thương mại. Như mọi khi, hãy kiểm tra lại license hiện tại trên repo trước khi xây sản phẩm dựa vào nó.


