使用 preg_match_all 配合精心設計的正則模式,可從 HTML 中提取所有 <a> 標籤的 href 屬性值與鏈接文本。
<?php
$url = 'https://example.com';
$html = @file_get_contents($url);
if ($html === false) {
die("無法獲取頁面內容");
}
// 正則模式:匹配 href 屬性與鏈接文本
// 模式解釋:href=[\"']? 匹配 href= 後的可選引號
// ([^\"']*) 捕獲組1:鏈接地址(非引號字符)
// [\"']?> 匹配結束引號與 >
// (.*?) 捕獲組2:鏈接文本(非貪婪)
// </a> 匹配閉合標籤
$pattern = '/href=[\"']?([^\"']*)[\"']?>(.*?)<\/a>/is';
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
$links = [];
foreach ($matches as $match) {
$links[] = [
'url' => $match[1],
'text' => trim(strip_tags($match[2])) // 去除嵌套標籤
];
}
// 去重(基於 URL)
$uniqueLinks = [];
$seenUrls = [];
foreach ($links as $link) {
if (!in_array($link['url'], $seenUrls)) {
$seenUrls[] = $link['url'];
$uniqueLinks[] = $link;
}
}
// 輸出結果
foreach ($uniqueLinks as $link) {
echo "URL: {$link['url']} | 文本: {$link['text']}<br>";
}
?>
<?php
function extractLinks($html, $baseUrl = '') {
$dom = new DOMDocument();
@$dom->loadHTML($html); // 抑制 HTML5 標籤警告
$xpath = new DOMXPath($dom);
$links = [];
$anchors = $xpath->query('//a[@href]');
foreach ($anchors as $anchor) {
$href = $anchor->getAttribute('href');
$text = trim($anchor->textContent);
// 處理相對路徑
if ($baseUrl && !preg_match('/^[a-z]+:/i', $href)) {
$href = rtrim($baseUrl, '/') . '/' . ltrim($href, '/');
}
// 過濾空鏈接、錨點、JavaScript
if (empty($href) || $href === '#' || stripos($href, 'javascript:') === 0) {
continue;
}
$links[] = ['url' => $href, 'text' => $text];
}
// 去重
return array_values(array_unique($links, SORT_REGULAR));
}
// 使用
$html = file_get_contents('https://example.com');
$links = extractLinks($html, 'https://example.com');
print_r($links);
?>
| 特性 | 正則表達式 | DOMDocument + XPath |
|---|---|---|
| 速度 | 快 | 較慢(需解析整個 DOM) |
| 準確性 | 易受異常 HTML 影響 | 高(瀏覽器級解析) |
| 內存佔用 | 低 | 高 |
| 相對路徑處理 | 需手動實現 | 可結合 base 標籤自動處理 |
| 推薦場景 | 簡單頁面、高性能需求 | 複雜頁面、生產環境 |
stream_context_create(['http'=>['timeout'=>10]])robots.txt 遵守爬蟲協議filter_var($url, FILTER_VALIDATE_URL)