首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 解析 User-Agent 取得瀏覽器名稱、版本與搜尋引擎爬蟲辨識

     編輯:PHP 相關知識

前言

$_SERVER['HTTP_USER_AGENT'] 包含用戶端瀏覽器、作業系統、裝置等資訊。雖然現代專案建議使用成熟函式庫(如 WhichBrowser/Parser、piwik/device-detector),但了解原生解析邏輯有助於除錯與輕量級需求。本文提供完整的瀏覽器/版本偵測函式與爬蟲辨識函式,並說明正則局限與最佳實踐。

瀏覽器與版本偵測函式

<?php
/**
 * 解析 User-Agent 取得瀏覽器名稱與版本
 *
 * @param string $ua User-Agent 字串,預設自動取 $_SERVER['HTTP_USER_AGENT']
 * @return string 格式:'BrowserName Version',失敗回傳 'Unknown Browser'
 */
function getUserBrowser($ua = null) {
    if ($ua === null) {
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    }
    if (empty($ua)) return 'Unknown Browser';

    $browser = '';
    $version = '';

    // 依優先順序匹配(較特殊的優先)
    // 1. Microsoft Edge (Chromium-based) - 必須在 Chrome 之前
    if (preg_match('/Edg\/([\d.]+)/i', $ua, $m)) {
        $browser = 'Microsoft Edge';
        $version = $m[1];
    }
    // 2. Chrome (含 Chromium 內核瀏覽器)
    elseif (preg_match('/(?:Chrome|CriOS)\/([\d.]+)/i', $ua, $m)) {
        $browser = 'Chrome';
        $version = $m[1];
    }
    // 3. Firefox
    elseif (preg_match('/Firefox\/([\d.]+)/i', $ua, $m)) {
        $browser = 'Firefox';
        $version = $m[1];
    }
    // 4. Safari (需排除 Chrome、Edge 等也包含 Safari 關鍵字的 UA)
    elseif (preg_match('/Version\/([\d.]+).*Safari/i', $ua, $m)) {
        $browser = 'Safari';
        $version = $m[1];
    }
    // 5. Internet Explorer 11 (Trident/7.0; rv:11.0)
    elseif (preg_match('/Trident\/7\.0.*rv:([\d.]+)/i', $ua, $m)) {
        $browser = 'Internet Explorer';
        $version = $m[1];
    }
    // 6. 舊版 IE (MSIE x.x)
    elseif (preg_match('/MSIE\s([\d.]+)/i', $ua, $m)) {
        $browser = 'Internet Explorer';
        $version = $m[1];
    }
    // 7. Opera (舊版 Presto 內核)
    elseif (preg_match('/Opera[\s\/]([\d.]+)/i', $ua, $m)) {
        $browser = 'Opera';
        $version = $m[1];
    }
    // 8. Opera (新版 Chromium 內核,OPR/xxx)
    elseif (preg_match('/OPR\/([\d.]+)/i', $ua, $m)) {
        $browser = 'Opera';
        $version = $m[1];
    }
    // 9. 其他較少見瀏覽器
    elseif (preg_match('/Maxthon/i', $ua)) {
        $browser = 'Maxthon';
    }
    elseif (preg_match('/UCBrowser\/([\d.]+)/i', $ua, $m)) {
        $browser = 'UC Browser';
        $version = $m[1];
    }
    elseif (preg_match('/QQBrowser\/([\d.]+)/i', $ua, $m)) {
        $browser = 'QQ Browser';
        $version = $m[1];
    }

    return $browser . ($version ? ' ' . $version : '');
}
?>

使用範例

<?php
// 測試各種 User-Agent
$testUAs = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
    'Mozilla/5.0 (Windows NT 10.0; Trident/7.0; rv:11.0) like Gecko',
    'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36',
];

foreach ($testUAs as $ua) {
    echo getUserBrowser($ua) . PHP_EOL;
}

/*
輸出範例:
Chrome 120.0.0.0
Firefox 121.0
Safari 17.2
Microsoft Edge 120.0.0.0
Internet Explorer 11.0
Chrome 120.0.0.0
*/
?>

搜尋引擎爬蟲辨識函式

<?php
/**
 * 判斷是否為搜尋引擎爬蟲
 *
 * @param string $ua User-Agent 字串
 * @return string|false 爬蟲名稱(如 'Googlebot', 'Baiduspider'),非爬蟲回傳 false
 */
function detectSearchBot($ua = null) {
    if ($ua === null) {
        $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    }
    if (empty($ua)) return false;

    $uaLower = strtolower($ua);

    // 爬蟲特徵字 => 顯示名稱對照表
    $bots = [
        'googlebot'         => 'Googlebot',
        'mediapartners-google' => 'Google AdSense',
        'adsbot-google'     => 'Google AdsBot',
        'baiduspider'       => 'Baiduspider',
        'bingbot'           => 'Bingbot',
        'msnbot'            => 'MSNBot',
        'yandexbot'         => 'YandexBot',
        'yandex'            => 'Yandex',
        'slurp'             => 'Yahoo Slurp',
        'duckduckbot'       => 'DuckDuckBot',
        'sogou'             => 'Sogou Spider',
        '360spider'         => '360Spider',
        'bytespider'        => 'Bytespider (Toutiao)',
        'ia_archiver'       => 'Alexa Crawler',
        'facebookexternalhit' => 'Facebook Crawler',
        'twitterbot'        => 'Twitter Bot',
        'linkedinbot'       => 'LinkedIn Bot',
        'whatsapp'          => 'WhatsApp Crawler',
        'telegrambot'       => 'Telegram Bot',
        'slackbot'          => 'Slack Bot',
        'discordbot'        => 'Discord Bot',
        'applebot'          => 'Applebot',
        'pinterest'         => 'Pinterest Bot',
    ];

    foreach ($bots as $pattern => $name) {
        if (strpos($uaLower, $pattern) !== false) {
            return $name;
        }
    }

    // 通用 bot 關鍵字兜底
    if (preg_match('/(bot|crawler|spider|archiver)/i', $ua)) {
        return 'Unknown Bot';
    }

    return false;
}
?>

整合應用:記錄訪客資訊

<?php
function logVisitorInfo() {
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    
    $browser = getUserBrowser($ua);
    $bot     = detectSearchBot($ua);
    
    $data = [
        'time'     => date('Y-m-d H:i:s'),
        'ip'       => $ip,
        'ua'       => $ua,
        'browser'  => $browser,
        'is_bot'   => $bot !== false,
        'bot_name' => $bot,
        'url'      => $_SERVER['REQUEST_URI'] ?? '',
        'referer'  => $_SERVER['HTTP_REFERER'] ?? '',
    ];
    
    // 寫入日誌檔或資料庫
    $logLine = json_encode($data, JSON_UNESCAPED_UNICODE) . PHP_EOL;
    file_put_contents(__DIR__ . '/logs/visitors.log', $logLine, FILE_APPEND | LOCK_EX);
    
    // 若為爬蟲,可選擇不執行昂貴的業務邏輯
    if ($bot) {
        // 可選:返回簡易頁面、不計入統計、不執行 Session 初始化等
    }
    
    return $data;
}
?>

正則解析的局限與建議

問題說明建議
UA 字串極其複雜多變瀏覽器版本更新、裝置種類爆炸、偽裝 UA、混合關鍵字生產環境優先使用 piwik/device-detector 或 WhichBrowser/Parser(Composer 安裝)
正則效能大量請求時逐條正則匹配有額外開銷編譯為單一大正則、或快取解析結果(Redis keyed by UA hash)
維護成本新瀏覽器/爬蟲持續出現,需持續更新規則使用社群維護的資料庫(Device Detector 定期釋出 regexes.yaml 更新)
偽裝 UA爬蟲偽裝成瀏覽器、瀏覽器偽裝成其他瀏覽器結合 IP 信譽、行為分析(請求頻率、JS 執行能力)綜合判斷

Composer 整合範例(推薦生產環境)

composer require piwik/device-detector

<?php
require 'vendor/autoload.php';

use DeviceDetector\DeviceDetector;
use DeviceDetector\Parser\Device\DeviceParserAbstract;

$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$dd = new DeviceDetector($ua);
$dd->parse();

echo '裝置: ' . $dd->getDeviceName() . PHP_EOL;
echo '品牌: ' . $dd->getBrand() . PHP_EOL;
echo '瀏覽器: ' . $dd->getClient('name') . ' ' . $dd->getClient('version') . PHP_EOL;
echo '作業系統: ' . $dd->getOs('name') . ' ' . $dd->getOs('version') . PHP_EOL;
echo '是否爬蟲: ' . ($dd->isBot() ? '是' : '否') . PHP_EOL;
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved