使用htaccess阻止指定爬虫失效,请求排查问题原因
问题描述
我尝试通过.htaccess拦截部分爬虫,但并未生效。我在PHP代码中追踪了不同爬虫的访问记录,记录下了绕过.htaccess拦截的爬虫的User-Agent:
Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)
当前使用的.htaccess代码:
SetEnvIfNoCase User-Agent "SemrushBot" bad_user Deny from env=bad_user SetEnvIfNoCase User-Agent "semrush" bad_user Deny from env=bad_user SetEnvIfNoCase User-Agent "BLEXBot" bad_user Deny from env=bad_user
我有两个疑问:
- 被.htaccess拦截的请求不会触发PHP脚本,这个认知是否正确?
- 我哪里操作有误?为何.htaccess无法拦截这些爬虫?
解答
关于被拦截请求是否触发PHP的问题
这个认知是正确的。当Deny from规则生效时,Apache会直接返回403 Forbidden响应,不会将请求传递给PHP处理器,所以PHP脚本不会被执行。如果你的PHP日志里出现了这些爬虫的记录,说明这些请求确实绕过了.htaccess的拦截规则。
为什么当前规则无法拦截爬虫
你的规则存在两个核心问题:
- 环境变量重复定义冲突:多次用
SetEnvIfNoCase设置同一个bad_user变量,后续的匹配会覆盖之前的结果,可能导致部分爬虫的匹配逻辑失效。 - 规则顺序逻辑问题:把
Deny from放在每个匹配规则之后,Apache处理时会逐个执行拦截,但这种写法无法合并所有匹配条件,容易出现漏判。
修正后的.htaccess规则
方案1:合并SetEnvIfNoCase规则
将所有目标User-Agent的匹配合并到一条规则中,统一设置环境变量后再执行拦截,避免冲突:
# 同时匹配所有目标爬虫的User-Agent(不区分大小写) SetEnvIfNoCase User-Agent "(SemrushBot|semrush|BLEXBot)" bad_user # 拦截匹配到的请求 Deny from env=bad_user
方案2:使用mod_rewrite实现(推荐)
mod_rewrite的规则逻辑更直观,兼容性也更好:
RewriteEngine On # 不区分大小写匹配目标爬虫的User-Agent RewriteCond %{HTTP_USER_AGENT} (SemrushBot|semrush|BLEXBot) [NC] # 返回403并终止后续规则处理 RewriteRule ^ - [F,L]
额外验证建议
- 确认服务器已启用对应模块:使用
SetEnvIfNoCase需要开启mod_setenvif和mod_access_compat;使用mod_rewrite则需要确保mod_rewrite已启用。 - 用curl模拟请求测试规则:
如果返回403状态码,说明规则已生效。curl -A "SemrushBot/7~bl" http://你的域名.com
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

