c.visit()未触发onhtml最常见原因是请求被目标站拦截导致403,因colly默认ua易被拒绝;需设自定义useragent、加onresponse打印状态码、处理重定向、传完整url、用limit()控并发、解压gzip、避开js渲染页、选稳定选择器、用连接池+channel安全存库。

为什么 c.Visit() 调了却没触发 OnHTML?
最常见原因不是代码写错了,而是请求根本没成功——被目标站拦在第一关。Colly 默认 UA 是 "colly - https://github.com/gocolly/colly",多数网站(尤其是 nginx 前置的)直接 403 拒绝,连 HTML 都不返回,OnHTML 自然不会执行。
- 必须显式设置
c.UserAgent,例如c.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" - 加
c.OnResponse(func(r *colly.Response) { log.Println(r.StatusCode, r.Request.URL) })确认是否真收到了 200 - 遇到 302 重定向默认不跟,需设
c.AllowURLRevisit = true(否则跳转后 URL 被去重丢弃) -
c.Visit()只接受完整 URL(含https://),传/page/2这类相对路径会静默失败
并发数设成 c.Async = true 就够了吗?
不够,而且非常危险。c.Async = true 只是开启异步模式,底层仍是单协程串行发请求;真正控制并发的是 c.Limit(),不设它等于没并发。
- 默认行为:无
LimitRule→ 所有请求排队,等前一个结束才发下一个 - 正确做法:用
c.Limit(&colly.LimitRule{DomainGlob: "*", Parallelism: 4})控制最大并行请求数 - 别盲目调高
Parallelism:设到 10+ 容易触发目标站风控,或本地too many open files错误 - 不同域名建议分开限流,比如 GitHub Pages 内容静态但反爬严:
&colly.LimitRule{DomainGlob: "*.github.io", Parallelism: 1}
OnHTML("div.title") 提取不到内容?先查这三件事
不是选择器写错,就是你看到的 HTML 和 Colly 拿到的根本不是一回事。浏览器里能看见,不代表服务器返回的就是那个结构。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 网页可能返回 gzip 压缩内容,但 Colly 默认不解压 → 加
c.OnResponse(func(r *colly.Response) { r.Collector.UnifyUTF8 = true })强制 UTF-8 并启用解压 - JS 渲染的内容(如 React/Vue SPA)Colly 看不见 → 检查源码里有没有
id="__next"或data-server-rendered,有就别硬扛,换 Puppeteer - 选择器太深、依赖属性顺序或空格 → 改用 class 名优先:
"h1.post-title"比"body > article > header > h1"更稳 - 调试技巧:在
OnResponse里打印string(r.Body[:min(200, len(r.Body))]),确认返回体是不是你预期的 HTML
结果存 MySQL 时连接池爆满,怎么安全写入?
Colly 回调本身就在 goroutine 里跑,每个 OnHTML 都开个 sql.Open(),几秒内就能打满数据库连接数。
- 全局只用一个
*sql.DB实例,调db.SetMaxOpenConns(10)和db.SetMaxIdleConns(5) - 别在回调里直接
db.Exec(),改用 channel 中转:ch := make(chan Item, 100),所有解析结果往里塞 - 另起 2~3 个 worker goroutine 消费 channel,顺序写入,避免并发冲突和连接争抢
- 如果某条记录插入失败,别 panic,记日志 + continue,否则整个采集流会卡死
真实项目里最常被忽略的,是错误传播路径:UA 没设好 → 403 → 不触发 OnResponse → 你以为漏了逻辑,其实是请求根本没发出去。先看 StatusCode,再调选择器。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










