需針對真實使用者與爬蟲呈現不同內容(如 SEO 渲染、隱藏廣告)?本文提供高效 PHP 判斷函式,透過 User-Agent 關鍵字陣列比對,回傳引擎名稱或布林值。
<?php
class BotDetector {
private static $engines = [
'google' => ['googlebot', 'mediapartners-google', 'adsbot-google'],
'bing' => ['bingbot', 'msnbot'],
'baidu' => ['baiduspider'],
'yandex' => ['yandexbot'],
'sogou' => ['sogou web spider', 'sogou push spider'],
'360' => ['360spider', 'haosouspider'],
'yahoo' => ['yahoo! slurp', 'yahoo! slurp china'],
'duckduckgo' => ['duckduckbot'],
'facebook' => ['facebookexternalhit'],
'twitter' => ['twitterbot'],
'linkedin' => ['linkedinbot'],
'telegram' => ['telegrambot'],
'whatsapp' => ['whatsapp'],
'slack' => ['slackbot'],
];
public static function detect(): ?string {
$ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? '');
if (!$ua) return null;
foreach (self::$engines as $name => $keywords) {
foreach ($keywords as $kw) {
if (strpos($ua, $kw) !== false) return $name;
}
}
return null;
}
public static function isBot(): bool {
return self::detect() !== null;
}
}
// 使用範例
if (BotDetector::isBot()) {
$engine = BotDetector::detect();
echo "來自 $engine 爬蟲";
// 輸出精簡 HTML、不載入廣告、不統計 GA 等
} else {
echo "真實使用者";
// 完整頁面、載入廣告、統計分析
}
?>
class BotDetector {
// ... 略 ...
public static function detectWithCache(): ?string {
$cacheKey = 'bot_detect_' . md5($_SERVER['HTTP_USER_AGENT'] ?? '');
// 假設使用 Redis/APCu
if (apcu_exists($cacheKey)) return apcu_fetch($cacheKey);
$result = self::detect();
apcu_store($cacheKey, $result, 3600); // 快取 1 小時
return $result;
}
}
| 場景 | 處理方式 |
|---|---|
| SEO 動態渲染 | 爬蟲回傳預渲染 HTML,使用者回傳 SPA |
| 隱藏敏感資訊 | 爬蟲不顯示電話、Email、價格等 |
| 分析統計排除 | GA、Matomo 等排除已知 Bot 流量 |
| 頻率限制差異 | 爬蟲給予較寬鬆 Rate Limit |
| 內容版本控制 | 爬蟲看到舊版快取,使用者看到新版 |
*.googlebot.com)。CF-IPCountry、CF-Connecting-IP 等標頭輔助判斷。DetectBot,將 $request->attributes->set('is_bot', BotDetector::isBot())。KernelEvents::REQUEST 註入屬性。BotDetect。require 'BotDetector.php'; 於入口檔頂部引入。