如何优化检测Google Bot等搜索引擎爬虫的PHP代码?
PHP搜索引擎爬虫检测代码优化方案
现有代码问题评估
你提供的原有代码只能实现基础的爬虫特征匹配,无法完美运行,存在以下明显缺陷:
- 语法错误:
preg_match()语句末尾多余的分号会导致解析报错,无法正常执行 - 匹配规则宽泛:普通浏览器UA、插件UA中也可能包含
bot等关键词,误判率高 - 性能冗余:简单的关键词匹配用正则表达式会产生不必要的性能开销,高并发场景下差距更明显
- 安全性不足:仅靠UA匹配无法识别伪造UA的恶意请求,也无法精准判断是否为Google Bot等官方爬虫
优化实现方案
轻量检测版本(适合对准确率要求不高的场景)
改用字符串匹配替代正则,性能提升明显,同时修复原代码的语法问题:
function _bot_detected(): bool { if (!isset($_SERVER['HTTP_USER_AGENT'])) { return false; } $userAgent = $_SERVER['HTTP_USER_AGENT']; $botKeywords = ['bot', 'crawl', 'slurp', 'spider', 'mediapartners']; foreach ($botKeywords as $keyword) { if (stripos($userAgent, $keyword) !== false) { return true; } } return false; }
精准官方爬虫检测版本(适合需要准确识别Google/Bing等官方爬虫的场景)
UA匹配+DNS双向验证,完全避免UA伪造的问题,是官方推荐的验证方案:
function is_official_crawler(): bool { // 先通过UA快速过滤非爬虫请求,减少后续DNS查询的性能开销 if (!isset($_SERVER['HTTP_USER_AGENT'], $_SERVER['REMOTE_ADDR'])) { return false; } $userAgent = $_SERVER['HTTP_USER_AGENT']; $officialKeywords = ['googlebot', 'bingbot', 'baiduspider', 'slurp', 'yandexbot', 'mediapartners']; $uaMatched = false; foreach ($officialKeywords as $keyword) { if (stripos($userAgent, $keyword) !== false) { $uaMatched = true; break; } } if (!$uaMatched) { return false; } // 反向DNS解析IP验证域名后缀 $ip = $_SERVER['REMOTE_ADDR']; $host = strtolower(gethostbyaddr($ip)); if (!$host) { return false; } $allowedSuffixes = ['.googlebot.com', '.google.com', '.search.msn.com', '.baidu.com', '.yandex.com', '.yandex.ru']; foreach ($allowedSuffixes as $suffix) { if (str_ends_with($host, $suffix)) { // 正向解析确认IP一致,防止PTR记录伪造 return gethostbyname($host) === $ip; } } return false; }
注:如果使用PHP版本低于8.0,没有内置
str_ends_with()函数,可以自行替换为substr($host, -strlen($suffix)) === $suffix实现相同效果。
内容的提问来源于stack exchange,提问作者Khan
相关产品推荐
相关产品推荐

