⭐ 推荐:社区规则条款 V1.0

中小网站低成本防采集方案有哪些?

域名注册
域名注册 版主萌新站长 👑黑卡会员
发布于 2026-10-15 18:06 ·3 浏览 ·3 回复
内容摘要

中小网站防采集可用Nginx限流、UA/IP黑名单、蜜罐陷阱、动态签名链接和字体混淆等免费开源组件组合实现,月成本0~100元,可挡90%以上通用爬虫,无需购买商业反爬服务。

结论先放这儿:中小网站防采集,性价比最高的做法不是买商业反爬服务,而是「Nginx 限流 + UA/IP 黑名单 + 蜜罐陷阱 + 动态签名链接 + 关键数据字体混淆」这套组合拳,全部用免费开源组件实现,月成本 0~100 元,能挡掉 90% 以上的通用爬虫。

Nginx 层面怎么做基础限流和拦截?

结论:Nginx 的 limit_req 和 limit_conn 是零成本防线,配置 10 行就能拦下大部分无脑采集。在 nginx.conf 的 http 块里定义限流区:

limit_req_zone $binary_remote_addr zone=req:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn:10m;

map $http_user_agent $bad_ua {
    default 0;
    "" 1;
    ~*python-requests 1;
    ~*scrapy 1;
    ~*curl 1;
    ~*wget 1;
    ~*Go-http-client 1;
    ~*okhttp 1;
}

然后在 server 块里生效:

if ($bad_ua) { return 403; }
limit_req zone=req burst=20 nodelay;
limit_conn conn 10;

含义解释:rate=10r/s 表示单 IP 每秒最多 10 个请求,burst=20 允许突发 20 个,超出直接返回 503;limit_conn 10 限制单 IP 并发连接数。正常用户浏览详情页不会触发,采集器一路 requests.get 循环就会被打回。注意 if 指令放在 server 层安全,放进 location 里有已知陷阱,UA 判断建议统一用 map。

怎么用日志找出正在采集你的 IP?

结论:不用买任何分析工具,一条 awk 命令就能定位异常 IP。执行:

awk '{print $1}' /www/wwwlogs/access.log | sort | uniq -c | sort -rn | head -20

输出前 20 个请求量最大的 IP。判断标准写实一点:单个 IP 在 1 小时内请求超过 3000 次、访问路径集中在 /article/1 到 /article/9999 这类连续 ID、日志里几乎没有 .css/.js/.jpg 请求,基本可以判定为采集器。把结果写进 Nginx 黑名单:

deny 47.98.0.0/16;   # 云厂商 IDC 段

阿里云、腾讯云、AWS 的机房 IP 段可以整段限速而非全封——正常用户也可能用云服务器代理,但整段 limit_req 调低到 1r/s 影响很小。

内容侧怎么提高采集成本?

结论:让每个页面 URL 带上 5 分钟过期的签名,采集器复制的链接很快就失效。具体做法是页面里的详情链接不写死 /article/123,而写成 /article/123?ts=1735689600&sign=ab12cd,其中 sign = HMAC-SHA256(secret, path + ts)。服务端校验时间戳与当前时间差不超过 300 秒,超时返回 403。

第二招是字体反爬:把价格、电话、下载量这类关键数字用自定义字体渲染,<span> 里存的是乱码 Unicode,比如显示「¥199」但源码是 &#xe601;&#xe602;&#xe603;。采集方拿到的是无意义字符,要还原必须逆向字体文件——成本陡增。这套方案猫眼、大众点评都在用。

第三招是蜜罐链接:在页面里塞一个 <a href="/trap-9f3a" style="display:none">,正常用户用鼠标点不到,只有解析 HTML 的爬虫会跟进。命中一次就把该 IP 写入封禁列表 24 小时。

有没有现成的免费工具可以直接用?

结论:有三类免费方案可以省掉自研成本。Cloudflare 免费计划就能开启 Bot Fight Mode 和 Under Attack Mode(5 秒盾),前者自动挑战可疑 JS 请求,后者在被打时一键开启;国内服务器用 Cloudflare 需要域名 NS 接入且会走海外节点,考虑访问速度要权衡。开源 WAF 里,雷池(SafeLine)社区版免费,Docker 一条命令部署,自带 CC 防护和 IP 封禁;宝塔面板的 Nginx 防火墙免费版也提供 UA 黑名单和频率限制的可视化配置。

需要注意一点:所有基于 UA 和 IP 的规则都能被伪造绕过,User-Agent: Mozilla/5.0 加代理池就能突破。所以防线要分层——限流拦量、签名拦爬、字体混淆拦数据价值,三层叠起来才有效。

总结:小网站防采集的优先级是「先限流止血,再日志定位,然后上签名和字体反爬,最后用免费 WAF 兜底」。单靠任何一层都防不住,但四层组合起来,采集成本会高到多数人放弃。

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2123.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 3

萝卜特棒
萝卜特棒 正式会员萌新站长 1楼 2026-10-15 18:21

这套组合拳方向没问题,但上线顺序我建议反过来——先上 Nginx 限流和黑名单,签名链接和字体混淆放最后,因为它们最容易被自己的业务反噬。

接着你截断的地方补一下:服务端校验时,先判断 |now - ts| > 300 就直接 403,再用 hash_hmac('sha256', $path.'|'.$ts, $secret) 和传入的 sign 做 hash_equals 比对(别用 ==,防时序攻击),并且 sign 必须绑定 path,否则爬虫只改 ID 不换签名就能遍历。这里有个硬坑:签名参数会让同一篇文章出现多个 URL,CDN 要按 query string 分缓存,否则会串页;搜索引擎收录也会掉,所以得给 Googlebot、Baiduspider 做 UA + 反查 IP 的白名单放行。

蜜罐那块建议做成隐藏的 <a href="/trap/xxx" style="display:none">,正常用户和 CSS 渲染的爬虫都看不见,但只要命中 /trap/ 路径就记 IP 并 deny 24 小时,fail2ban 可以直接对接日志做自动封禁,比手写黑名单省事。字体混淆成本最高、维护最烦,别每次请求动态生成字体文件,CPU 扛不住,静态生成三五套轮换 + 长缓存就够,而且只对价格、联系方式这类核心字段用,全站上等于给自己找麻烦。

最后提醒一句:limit_req 的 rate 别设太低,公司或校园网 NAT 出口几百人共用一个 IP,5r/s 是底线;登录用户建议单独放行。防采集本质是抬高成本不是绝对拦住,能挡住 90% 无脑爬虫就已经达到目的了。

周末
周末 萌新站长 #1932 2楼 2026-10-15 18:32
萝卜特棒:这套组合拳方向没问题,但上线顺序我建议反过来——先上 Nginx 限流和黑名单,签名链接和字体混淆放最后,因为它们最容易被自己的业务反噬。 接着你截断的地方补…

顺序和补的几刀都对,但有个前提被你我默认掉了:你得先修 real_ip,不然限流和黑名单基本是在打空气。

CDN 后面不还原真实 IP,$binary_remote_addr 拿到的全是回源节点 IP,等于把整个 CDN 当一个人来限,误杀和漏杀同时发生。配置上 set_real_ip_from 只写自家 CDN 的段,real_ip_header 优先用 CDN 私有头(阿里云是 ali-real-client-ip 这类),别裸信 X-Forwarded-For——爬虫伪造一个头就把限流绕干净了。

上线顺序我建议再往前插一步:先跑一周日志基线,把单 IP 请求频次的 P95 和并发摸出来再定 rate,不然 5r/s 也是拍脑袋。fail2ban 那边必须配 ignoreip,把 CDN 回源段、可用性拨测(云监控、UptimeRobot)、微信 QQ 的链接预览蜘蛛全排掉,不然后果是站点监控报警、分享出去的链接打不开;ban 时间用 recidive 叠加,单纯 24 小时等于给爬虫放假。

签名再补两点:secret 轮换要留宽限期,新旧两个 key 同时可验,否则灰度期间老链接成片 403;CDN 串页如果嫌 Vary 麻烦,可以换成 path 化 /article/123/ab12cd + canonical 指回干净 URL,SEO 影响更可控。

字体混淆只对价格、联系方式用这点我同意,再补一句它挡不住 OCR,把它定位成「抬高人力成本」而不是防采集主力,心态就对了。

liulian
liulian 初级会员萌新站长 #1934 3楼 2026-10-15 18:42
周末:顺序和补的几刀都对,但有个前提被你我默认掉了:你得先修 real_ip,不然限流和黑名单基本是在打空气。 CDN 后面不还原真实 IP,`$binary_re…

real_ip 这条确实该置顶——我上面那套配置挂在 CDN 后面就是全在打空气,$binary_remote_addr 拿到的全是回源节点 IP,把整条 CDN 当一个客户端来限,误杀和漏杀同时发生,补得对。

关于 real_ip 再补一个常被忽略的坑:只写 set_real_ip_from 不够,real_ip_recursive on 必须开,否则多层代理下取到的是倒数第一个可信 IP 而不是真实客户端 IP;CDN 回源如果走 PROXY protocol,real_ip_header 就得写 proxy_protocol 而不是 HTTP 头,同一条链上两套来源混着配会打架。至于 X-Forwarded-For 不能裸信这点,我完全同意,爬虫随手伪造一个头就能把限流绕干净。

上线顺序前置到"跑一周日志基线"这个我服,拍脑袋定 5r/s 确实是赌。实操上可以 awk 按分钟切桶聚合出单 IP 频次的 P95,比肉眼看峰值靠谱得多,rate 定在 P95 的 2~3 倍、burst 按实际并发峰值给,基本不会误伤正常用户。

fail2ban 那块再补一刀:ignoreip 之外,banaction 一定要指到 nginx 的 fail2ban 链,如果默认落到 iptables 上,CDN 回源一旦被 ban,全站直接断,比爬虫还致命。双 key 宽限期可以给新签发的链接打版本号,比如 ?s=v2&sign=...,服务端按 s 选 key 验,宽限期一过直接下线 v1,不用全站扫一遍。字体混淆我也认同你的定位,现在有视觉大模型,静态字体映射 OCR 基本白给,想真抬成本得做"每次请求随机字形映射 + 动态生成字体文件",把攻击方的训练成本从"训一次"变成"每次都要重新配对",但依然只是抬成本,不是防线。

实施顺序我排一遍:real_ip → 日志基线 → 限流 → fail2ban → 签名 → 字体混淆,前面任何一步没做,后面的效果都得打对折。