不能。Colly本身不执行JavaScript,无法获取document.write、fetch或Vue/React动态渲染的内容,仅能抓取初始HTML;需改用chromedp、playwright-go,或分析XHR接口、解析script标签内JSON数据。

Colly 能否直接抓取 JavaScript 渲染的动态内容
不能。Colly 本身不执行 JavaScript,遇到 document.write、fetch 加载的数据、Vue/React 渲染的 DOM,它拿到的就是初始 HTML(常为空容器或占位符)。你看到页面有内容,但 c.OnHTML("div.item") 匹配不到,大概率是这个原因。
常见错误现象:本地浏览器能看见列表,Colly 抓回来的 r.Body 里只有 <div id="app"></div>;或者 e.Text 返回空字符串,但元素明明在 DevTools 里可见。
- 真需要渲染,得桥接浏览器引擎:用
chromedp或playwright-go替代 Colly,或让前端暴露 SSR 接口 - 先确认目标是否真依赖 JS:打开浏览器开发者工具 → Network → 刷一次页面 → 看 XHR/Fetch 请求,找到真实数据接口,直接用 Colly 请求那个 API(带必要
Referer、Authorization) - 部分网站会把关键数据塞进
<script>标签的 JSON 字符串里,可用c.OnHTML("script", func(e *colly.HTMLElement)提取后用json.Unmarshal解析,比渲染快且稳定
设置 User-Agent 和 Referer 是反爬第一道门槛
空 User-Agent 或默认值(如 Go-http-client/1.1)基本秒回 403;没有 Referer 时,某些接口会拒绝响应或返回假数据。这不是“建议”,是硬性准入条件。
实际配置必须显式写死,别依赖默认:
立即学习“go语言免费学习笔记(深入)”;
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
c.UserAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"—— 每次启动新 Collector 都要设 -
c.OnRequest(func(r *colly.Request) { r.Headers.Set("Referer", "https://example.com/") })—— Referer 值需与上一页 URL 一致,不能写死成首页 - 别用随机 UA 列表轮换:多数网站不校验 UA 真伪,但频繁切换反而触发风控;固定一个主流 UA 更安全
Cookie 管理失效的三个静默丢弃场景
Colly 的 CookieJar 看似自动,但以下情况 cookie 会被底层 net/http 静默丢弃,无报错、无日志,请求就变成“未登录”状态:
- 目标域名返回
Set-Cookie带Secure属性,但你用http://(非 TLS)访问 → 改用https:// -
SameSite=Strict或SameSite=Lax下,跨域跳转时 cookie 不随请求发出 → 检查c.Visit()的 URL 是否与登录域名完全一致(含子域、协议、端口) - 手动调用
c.SetCookies(url, cookies)时,url参数必须是完整 URL(如"https://site.com/login"),不能只传域名或路径,否则 jar 不匹配
并发控制 + 随机延迟才是防 429 的核心
单靠 c.Limit(&colly.LimitRule{Parallelism: 2}) 不够。网站看的是单位时间请求数(QPS),不是并发数。你开 2 个 goroutine 但每秒发 20 次请求,照样被限流。
真正有效的组合:
-
c.Limit(&colly.LimitRule{DomainGlob: "*", Parallelism: 1, Delay: 1 * time.Second, RandomDelay: 500 * time.Millisecond})—— 强制串行 + 基础延迟 + 抖动,打乱规律性 - 全局 QPS 控制必须外置:所有节点共用 Redis + Lua 脚本计数器,每次
c.Visit()前INCR并检查阈值,而非只靠本地LimitRule - 遇到
429响应时,别只time.Sleep:记录该域名退避时间,后续请求主动延迟,并更新 Redis 中的节流状态
动态页面和反爬策略的复杂点不在代码长度,而在 HTTP 协议细节与服务端行为的咬合——比如 SameSite 规则、Secure cookie 的 TLS 绑定、Referer 的路径精度。这些地方错一点,整个会话就断在看不见的地方。

















