结论:蜘蛛抓取的带宽消耗 = 日抓取次数 × 平均单次响应字节数 ÷ 86400 秒。以 gzip 后的 HTML 单次响应 30 KB 计算,每天 10 万次抓取只占 0.27 Mbps 平均带宽、月流量 86 GB;涨到 100 万次/天,平均带宽 2.7 Mbps、月流量 858 GB。真正决定带宽账单的不是"抓了多少次",而是"每次回给蜘蛛多少字节",以及有没有用 304 和压缩。
蜘蛛抓取的带宽消耗怎么算?
先记住三个换算锚点:1 Mbps 持续跑满一个月约等于 324 GB 流量;1 GB = 1,048,576 KB;日流量转平均带宽用 字节数 × 8 ÷ 86400。
月流量(GB)= 日抓取次数 × 单次响应(KB)× 30 ÷ 1,048,576。
平均带宽(Mbps)= 日流量(GB)× 8192 ÷ 86400 ≈ 日流量 × 0.0948。
举例:Baiduspider 每天抓 50 万次,平均每次回 30 KB(gzip 后的 HTML),日流量 = 500,000 × 30 ÷ 1,048,576 = 14.3 GB,平均带宽 1.36 Mbps,月流量 429 GB。这个量级对一台 5 Mbps 带宽的服务器不算负担,但如果单次响应变成 300 KB(页面里塞了大图、未压缩),同样的抓取次数直接变成 143 GB/天和 13.6 Mbps,账就完全不同了。
抓取量涨到不同量级,分别吃掉多少带宽?
下表按"单次响应 30 KB"这个 gzip 后 HTML 的典型值推算,峰值带宽按平均值的 3 倍预留:
| 日抓取次数 | 单次响应 | 日流量 | 月流量 | 平均带宽 | 峰值参考 |
|---|
| 10 万 | 30 KB | 2.9 GB | 86 GB | 0.27 Mbps | 1 Mbps |
| 100 万 | 30 KB | 28.6 GB | 858 GB | 2.7 Mbps | 8 Mbps |
| 100 万 | 100 KB(未压缩) | 95.4 GB | 2.86 TB | 9.0 Mbps | 27 Mbps |
| 100 万 | 300 KB(含图) | 286 GB | 8.6 TB | 27 Mbps | 80 Mbps |
| 1000 万 | 30 KB | 286 GB | 8.6 TB | 27 Mbps | 80 Mbps |
按 0.8 元/GB 的按量计费测算,858 GB/月对应 686 元,2.86 TB/月对应 2288 元。换成 CDN 回源+边缘缓存后成本通常降到三分之一以下。
为什么同样的抓取量,流量能差 10 倍?
差在四个变量上,按影响从大到小排列:单次响应体、是否返回 304、是否压缩、被抓的 URL 是不是垃圾页。
单次响应体:蜘蛛抓 HTML 时不会全量下载图片和视频,但如果你的页面是服务端渲染带内联 base64 图片、或者蜘蛛跟着抓了 PDF/大附件,单次响应能从 30 KB 跳到几百 KB。
304:配置 ETag 或 Last-Modified 后,蜘蛛重复抓取未变更的页面时服务器只回 304 状态和响应头,约 200-500 字节,相比 30 KB 省下 98% 以上。日抓 100 万次的站点,光这一项就能把 858 GB/月压到 20 GB/月以内。
压缩:nginx 开 gzip 后,HTML 通常从 80-150 KB 降到 20-40 KB,省 70%-80%;开 brotli 还能再降 15% 左右。
垃圾 URL:带 ?sessionid=、?sort= 这类参数的筛选页、站内搜索结果页、无限翻页的日历页,会成倍放大抓取次数却不带任何流量价值。robots.txt 里 Disallow 掉它们,是性价比最高的一刀。
怎么在服务器上实测蜘蛛到底用了多少流量?
nginx 默认 combined 日志格式里,$body_bytes_sent 是第 10 个字段,直接 awk 累加即可。
grep -Ei 'Baiduspider|Googlebot|bingbot|Sogou|360Spider|YisouSpider' access.log \
| awk '{s+=$10} END {printf "%.2f GB\n", s/1024/1024/1024}'
想按蜘蛛分开统计:
awk '{ua=""; for(i=1;i<=NF;i++) if($i ~ /spider|bot/i) ua=$i; if(ua!="") b[ua]+=$10} END {for(k in b) printf "%s %.2f MB\n", k, b[k]/1024/1024}' access.log
统计出来的总字节数除以 86400 再乘 8,就是这只蜘蛛占用的平均 Mbps。建议按 7 天窗口统计,避开单日波动。
怎么把蜘蛛抓取的带宽压下来?
按投入产出比排序,前两步能解决 90% 的问题。
- 开压缩:nginx 配
gzip on; gzip_types text/html text/css application/javascript application/json; gzip_min_length 1024;,Brotli 同理加 brotli on;。
- 开条件请求:确保返回
ETag 或 Last-Modified,让重复抓取走 304。
- 收窄抓取面:robots.txt 屏蔽参数页、站内搜索、
/search?、/tag/ 分页过深的路径。
- 限速:百度搜索资源平台可调"抓取频次",Google Search Console 的"抓取速度"设置能直接下调 Googlebot 速率。
- 静态化 + CDN:把蜘蛛高频抓的栏目页、详情页缓存到边缘节点,回源流量归零。
- 监控告警:日志里蜘蛛流量占比超过总流量 30% 时排查,正常内容站的蜘蛛流量占比通常在 10%-20%。
注意第 5 步不要把蜘蛛单独导到一份内容不同的页面,那属于 cloaking,会被判定作弊;正确做法是同一份内容走 CDN 缓存。
总结一句:蜘蛛抓取的带宽不是"次数 × 神秘系数",而是可以直接用日志算出来的确定值。先算清基线(日抓取次数、单次响应字节),再按压缩、304、屏蔽垃圾 URL、限速、CDN 的顺序优化,100 万次/天的抓取量完全可以把月流量控制在 100 GB 以内。