Colly的Collector不能跨域名复用,因AllowedDomains仅为过滤器,LimitRule按域名匹配生效,混用会导致限流错配、UA/cookie冲突及重试逻辑干扰;每个业务域名须新建独立Collector实例,并精确配置DomainGlob、UserAgent、CacheDir等参数。

直接用 colly.NewCollector() 启动并发爬取,大概率会触发目标站风控、本地文件描述符耗尽,或数据写入崩掉——微服务不是把爬虫代码扔进 Docker 就完事,得拆清职责、控住资源、隔离策略。
为什么 Collector 不能跨域名复用
Colly 的 AllowedDomains 是过滤器,不是隔离边界;LimitRule 按域名匹配生效,混用会导致限流错配、UA/cookie 冲突、重试逻辑互相干扰。比如同时抓 news.example.com 和 api.example.com,一个要 2 并发 + 1s delay,另一个需 6 并发 + 无 delay,共用 collector 就会全乱套。
- 每个业务域名(或子域)必须新建独立
colly.Collector实例 -
LimitRule中的DomainGlob要精确匹配,例如"*.github.io"不会命中docs.github.io(需写成"docs.github.io"或"*.github.io"并确认通配符行为) - 不同 collector 的
UserAgent、CacheDir、MaxDepth应按目标站点策略单独设,别图省事全局复用
并发数和 Delay 怎么设才不被封
并发不是越大越好。Parallelism: 10 在没加 delay 时,等效于瞬间打满连接池,多数中小型网站会直接返回 429 Too Many Requests 或静默丢包。真实压测中,稳定窗口往往在 2–4 并发 + 随机 delay。
- 起手设
Parallelism: 2,观察响应码分布:若429> 5%,立刻降为 1 并加Delay: 2 * time.Second - 用
RandomDelay替代固定 delay:c.Limit(&colly.LimitRule{DomainGlob: "*", Parallelism: 3, RandomDelay: 1 * time.Second}),比固定间隔更难被模式识别 - 避免在
OnRequest里手动time.Sleep——它阻塞的是当前 goroutine,但 Colly 的请求调度是异步的,反而导致并发失控
微服务里怎么安全存数据到 MySQL
Colly 回调函数天然运行在 goroutine 里,如果每个 OnHTML 都开新 sql.Open 或直接 db.Exec,几秒内就会打爆数据库连接池,报错 "dial tcp: lookup xxx: no such host" 或 "too many connections"。
立即学习“go语言免费学习笔记(深入)”;
- 全局只初始化一个
*sql.DB,调用db.SetMaxOpenConns(10)和db.SetMaxIdleConns(5) - 写入走 channel + worker 模式:回调里只把结构体发进
chan Result,另起 1–3 个 goroutine 消费并批量INSERT - 字段含逗号、换行、引号?别手拼 SQL —— 用
db.Stmt预编译 +args...参数化,防注入也防 CSV 解析错位
任务调度和服务发现怎么接上
微服务不是跑通单机爬虫就行,得能被调度、可观测、可扩缩。Colly 本身不提供服务注册,得靠外部机制桥接。
- 任务下发走 Redis queue:
queue.RedisStorage要显式设Password和DB,空密码不能省略为"",否则连接失败静默忽略 - 每个爬虫节点启动时向 Consul/Etcd 注册
health check接口,路径如/health,返回{ "status": "up", "collector_count": 2 } - Web 调试页
debug.WebDebugger默认绑定localhost:7777,K8s 里必须改成0.0.0.0:7777并开 readiness probe,否则流量进不来
最常被跳过的点:所有 HTTP 层配置(超时、重试、gzip 解压)都得通过 c.WithTransport 注入自定义 http.Transport,Colly 的默认 transport 没设 MaxIdleConnsPerHost,跑久了会卡在 net/http: timeout awaiting response headers。


















