抓取遠端網頁的 <title> 是爬蟲、書籤工具、SEO 審計的基礎需求。本文對比三種原生 PHP 方案,分析優劣與適用場景,附帶編碼自動偵測與正則提取細節。
<?php
function getTitleByCurl($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 10,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; TitleBot/1.0)',
CURLOPT_SSL_VERIFYPEER => false, // 僅測試環境建議關閉
]);
$html = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200 || !$html) return null;
// 編碼偵測與轉換
if (stripos($html, 'utf-8') === false && stripos($html, 'utf8') === false) {
$html = @iconv('GBK', 'UTF-8//IGNORE', $html);
}
if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $m)) {
return trim($m[1]);
}
return null;
}
echo getTitleByCurl('https://www.jb51.net');
優點: 支援 HTTPS、重定向、Cookie、Proxy、自定義 Header、錯誤處理、超時控制。
缺點: 需安裝 php-curl 擴展(現代主機多預裝)。
<?php
function getTitleByFile($url) {
$lines = @file($url, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (!$lines) return null;
$html = implode('', $lines);
if (stripos($html, 'utf-8') === false) {
$html = @iconv('GBK', 'UTF-8//IGNORE', $html);
}
// 注意:eregi 已棄用,改用 preg_match
if (preg_match('/<title[^>]*>(.*?)<\/title>/is', $html, $m)) {
return trim($m[1]);
}
return null;
}
缺點: 無法控制 Header、超時、重定向;allow_url_fopen 需開啟;大檔案記憶體佔用高。
<?php
function getTitleByFGC($url) {
$html = @file_get_contents($url);
if (!$html) return null;
if (stripos($html, 'utf-8') === false) {
$html = @iconv('GBK', 'UTF-8//IGNORE', $html);
}
// 純字串定位,避免正則回溯效能問題
$start = stripos($html, '<title>');
if ($start === false) return null;
$start += 7; // strlen('<title>')
$end = stripos($html, '</title>', $start);
if ($end === false) return null;
return trim(substr($html, $start, $end - $start));
}
缺點: 同 file(),且無法自訂 User-Agent,易被反爬蟲屏蔽。
| 指標 | cURL | file() | file_get_contents |
|---|---|---|---|
| HTTPS 支援 | ✅ 完整 | ⚠️ 需 OpenSSL | ⚠️ 需 OpenSSL |
| 自訂 Header/UA | ✅ | ❌ | ❌ |
| 重定向跟隨 | ✅ | ❌ | ❌ |
| 超時控制 | ✅ | ❌ | ⚠️ stream context |
| 錯誤碼獲取 | ✅ | ❌ | ❌ |
| 記憶體效率 | ✅ 可串流 | ❌ 全量載入 | ❌ 全量載入 |
正則對付 HTML 易因屬性順序、換行、註釋而失效。生產環境建議:
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML('<?xml encoding="UTF-8"?>' . $html);
libxml_clear_errors();
$titleNode = $dom->getElementsByTagName('title')->item(0);
$title = $titleNode ? trim($titleNode->textContent) : null;
此法天然處理實體編碼、巢狀標籤、大小寫差異,極大提升穩健度。
file_get_contents + 字串定位。mb_detect_encoding 或檢查 Content-Type Header)。robots.txt、設定合理 User-Agent、限制請求頻率,做個友善的爬蟲公民。