船说 CMS 怎么屏蔽恶意爬虫
照着这篇做完,你能让船说 CMS 站点挡住绝大多数采集脚本和垃圾蜘蛛,同时不误伤百度、必应这些正规搜索引擎。
恶意爬虫的典型特征有三个:UA 是 python-requests、Go-http-client、Scrapy 这类程序名;同一个 IP 一秒钟请求几十次;只抓详情页不抓静态资源。下面按「先看日志 → 再挡域名外 → 再挡服务器层 → 最后挡程序层」的顺序来做,从便宜好用的办法开始。
第一步:先确认是谁在爬
这一步的目的是找出真实作案的 UA 和 IP,别凭感觉封。进宝塔面板,左侧「网站」→ 找到你的船说 CMS 站点 → 点「设置」→「网站日志」,下载当天的 access.log。也可以直接在服务器上执行:
awk '{print $1}' /www/wwwlogs/你的域名.log | sort | uniq -c | sort -rn | head -20
awk -F'"' '{print $6}' /www/wwwlogs/你的域名.log | sort | uniq -c | sort -rn | head -20
第一条看哪个 IP 请求量最大,第二条看哪个 UA 出现次数最多。把出现几千次、明显不是浏览器的 UA 记下来。
注意:如果站点套了 CDN,日志里的 IP 是 CDN 节点 IP,不是真实访客 IP,这种情况要先去 CDN 后台看日志,或者让 Nginx 读取 X-Forwarded-For 头。
第二步:写 robots.txt(只挡讲规矩的)
在站点根目录(和 index.php 同级)新建 robots.txt,内容:
User-agent: *
Disallow: /search.php
Disallow: /*?*
Crawl-delay: 5
这一步能挡掉遵守协议的爬虫,对恶意采集器完全无效,但成本几乎为零,顺手做掉。
第三步:Nginx 层封 UA 加限速(最有效)
在宝塔「网站」→ 站点「设置」→「配置文件」里,在 server { } 内部加:
if ($http_user_agent ~* (SemrushBot|AhrefsBot|MJ12bot|DotBot|BLEXBot|PetalBot|ZmEu|masscan|python-requests|Go-http-client|Scrapy|zgrab)) {
return 403;
}
保存后 Nginx 会自动重载。再对单 IP 做限速,在 http 段(宝塔里是 nginx.conf 的 http 块)加:
limit_req_zone $binary_remote_addr zone=cmsip:10m rate=30r/m;
在站点的 location / 里加一行 limit_req zone=cmsip burst=10 nodelay;。意思是单 IP 每分钟最多 30 次请求,突发允许 10 次。
注意:限速会连正规蜘蛛一起限,务必把百度、必应加白名单。在站点
server { }内加:
> if ($http_user_agent ~* (Baiduspider|bingbot|Googlebot|Sogou web spider|YisouSpider|360Spider)) { > set $limit_bypass 1; > } >更稳妥的做法是百度站长平台里的「抓取频次」调低,而不是直接封禁。
第四步:虚拟主机用户用 .htaccess
如果你的船说 CMS 装在只支持 Apache 的虚拟主机上,在根目录建 .htaccess:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (SemrushBot|AhrefsBot|MJ12bot|python-requests|Scrapy|Go-http-client) [NC]
RewriteRule .* - [F,L]
保存即生效,不需要重启。
第五步:程序层兜底
前几层都被绕过时(比如 UA 伪装成 Chrome),在船说 CMS 的入口文件 index.php 最顶部 <?php 之后插入拦截代码:
$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
$bad = ['semrushbot','ahrefsbot','mj12bot','dotbot','python-requests','go-http-client','scrapy'];
foreach ($bad as $b) {
if ($ua !== '' && strpos($ua, $b) !== false) {
header('HTTP/1.1 403 Forbidden');
exit;
}
}
再封掉整段 IP,比如某个 C 段一直在扫:
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'];
$block = ['45.155.205.', '198.98.51.'];
foreach ($block as $p) {
if (strpos($ip, $p) === 0) { header('HTTP/1.1 403 Forbidden'); exit; }
}
注意:改 index.php 前先备份。船说 CMS 升级时会覆盖入口文件,升级后要把这段代码补回去。
另外,船说 CMS 后台一般有「蜘蛛统计 / 访问统计」入口(不同版本菜单名可能是「系统」或「工具」下),可以进去看近期蜘蛛名单,确认新增的可疑 UA 再补进上面的黑名单。
第六步:套一层 CDN 或 WAF
Cloudflare 免费版就够用:登录后选你的域名,进 Security → WAF → Custom rules,新建规则,Field 选 User Agent,Operator 选 contains,Value 填 SemrushBot,Action 选 Block。也可以直接开 Security → Bots → Bot Fight Mode 开关。国内站可以用宝塔的「网站防火墙」插件(网站 → 设置 → 网站防火墙 → 全局配置 → UA 黑名单),把 UA 一条条加进去,比手改配置文件省事。
小结
- 先看 access.log 找出真实 IP 和高频 UA,再动手封,别凭感觉。
- Nginx 的 UA 黑名单加单 IP 限速是性价比最高的一层,30 次/分钟对正常用户完全够用。
- 一定把 Baiduspider、bingbot、Googlebot 加白,否则收录会掉。
- 虚拟主机用 .htaccess,宝塔用户用防火墙插件,能不改配置文件就不改。
- 程序层 index.php 的拦截是兜底,注意船说 CMS 升级会覆盖文件。
- robots.txt 只挡君子不挡小人,别指望它解决问题。
原文链接:https://www.gj0.com/thread-487.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。