Colly 分布式爬虫:让爬虫军团协同作战

2025-07-11 17:45 更新

当单机爬虫速度太慢、IP 被封或任务量巨大时,就需要把“单兵”升级成“军团”——分布式爬虫。
本文用最接地气的方式,带你用 Colly 快速实现“多 IP 同时爬”与“多台机器一起爬”。

一、为什么需要分布式?

单机痛点 分布式优势
一个 IP 频繁请求 → 被封 多 IP 轮流请求 → 降低被封风险
一台机器带宽/CPU 有限 多台机器并行 → 线性提速
内存里存 URL → 程序挂了全丢 统一存储 → 断点续爬

二、方案 1:代理池(轻量级分布式)

适用场景:

只有一台机器,但想“假装”成很多机器。

1. 使用 Colly 内置的轮询代理

package main


import (
    "github.com/gocolly/colly/v2"
    "github.com/gocolly/colly/v2/proxy"
)


func main() {
    c := colly.NewCollector()


    // 把代理地址换成你自己的
    p, _ := proxy.RoundRobinProxySwitcher(
        "http://127.0.0.1:8080",
        "socks5://127.0.0.1:1080",
        "http://user:pass@ip:port", // 带账号密码示例
    )
    c.SetProxyFunc(p)


    c.OnResponse(func(r *colly.Response) {
        println("用代理", r.Request.ProxyURL, "抓到", len(r.Body), "字节")
    })


    c.Visit("https://www.w3cschool.cn/")
}

运行步骤

  1. 本地启动 2 个代理(如 Squid、Clash、TinyProxy)。
  2. go run main.go → 看到不同代理 IP 轮流上阵。

2. 自定义随机代理

想完全随机?自己写个函数:

import "math/rand"


var proxyList = []string{
    "http://127.0.0.1:8080",
    "http://127.0.0.1:8081",
}


func randomProxy(_ *http.Request) (*url.URL, error) {
    return url.Parse(proxyList[rand.Intn(len(proxyList))])
}


c.SetProxyFunc(randomProxy)

三、方案 2:多节点爬虫(真·分布式)

适用场景:

多台云服务器 / 本地多台电脑,需要统一调度。

1. 架构图

┌-------------┐         ┌-------------┐
│  调度器      │ <-----> │  存储中心    │
│  (HTTP API)  │         │  (Redis)    │
└-------------┘         └-------------┘
       ▲                        ▲
       │                        │
┌-------------┐         ┌-------------┐
│  爬虫节点 A  │         │  爬虫节点 B  │
└-------------┘         └-------------┘

  • 调度器:把“待爬 URL”分发给节点。
  • 存储中心:Redis/MySQL 统一存“已爬 URL + Cookie”。
  • 爬虫节点:每台机器跑一个 Colly 程序,只负责抓取。

2. 快速落地:Redis 存储

Colly 官方提供了 redisstorage,直接拿来用:

go get github.com/gocolly/redisstorage/v2

package main


import (
    "github.com/gocolly/colly/v2"
    "github.com/gocolly/colly/v2/storage/redisstorage"
)


func main() {
    // 1. 连接 Redis
    store, _ := redisstorage.New(
        &redisstorage.Options{Address: "127.0.0.1:6379"},
    )


    // 2. 创建收集器并挂载存储
    c := colly.NewCollector()
    c.SetStorage(store)


    // 3. 正常写业务逻辑
    c.OnHTML("title", func(e *colly.HTMLElement) {
        println("标题:", e.Text)
    })


    c.Visit("https://www.w3cschool.cn/")
}

效果

  • 任意节点重启 → 从 Redis 恢复“已爬 URL”,不会重复爬。
  • 节点横向扩容 → 只需再开一台机器跑同一份代码。

3. 进阶:Google App Engine 部署

Colly 内置 GAE 支持,只需加一行:

c.Appengine(req) // req 是 *http.Request

部署到 GAE 标准环境即可自动伸缩实例。

四、实战小结

场景 推荐方案 关键词
只有一台电脑 代理池 + 轮询 RoundRobinProxySwitcher
多台云服务器 Redis 存储 + 多节点 redisstorage
无服务器 Google App Engine c.Appengine

五、下一步:动手实验

  1. 打开 终端 → 新建 Go 文件。
  2. 复制“代理池”示例 → 填入你的代理 → 运行。
  3. 进阶:本地启动 Redis → 跑“Redis 存储”示例 → 开两个终端同时跑,观察是否共享已爬 URL。
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号