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

PHP 正則提取網頁所有鏈接:兩種實用方法

     編輯:PHP 相關知識

需求分析

從 HTML 內容中提取所有 <a> 標籤的 href 屬性及鏈接文本,常用於爬蟲、鏈接檢測、內容分析。

方法一:針對標準 標籤的正則(輕量)

<?php
function extractLinks($html) {
    // 匹配 text ,支持單雙引號、屬性順序不固定
    $pattern = '/]*href\s*=\s*["\']([^"\']+)["\'][^>]*>(.*?)<\/a>/is';
    
    if (preg_match_all($pattern, $html, $matches)) {
        return array_combine($matches[1], $matches[2]); // [url => text]
    }
    return [];
}

$html = '示例 頁面';
$links = extractLinks($html);
print_r($links);
/*
Array
(
    [https://example.com] => 示例
    [/page] => 頁面
)
*/
?>

局限: 無法處理嵌套標籤、JS 動態生成、跨行屬性等複雜情況。

方法二:基於 DOMDocument 解析(健壯、標準)

<?php
function extractLinksDOM($html, $baseUrl = '') {
    libxml_use_internal_errors(true); // 抑制 HTML5 解析警告
    $dom = new DOMDocument();
    $dom->loadHTML('' . $html); // 強制 UTF-8
    libxml_clear_errors();
    
    $links = [];
    foreach ($dom->getElementsByTagName('a') as $a) {
        $href = $a->getAttribute('href');
        $text = trim($a->textContent);
        
        if ($href !== '') {
            // 處理相對路徑
            if ($baseUrl && !preg_match('/^[a-z]+:/i', $href)) {
                $href = rtrim($baseUrl, '/') . '/' . ltrim($href, '/');
            }
            $links[$href] = $text;
        }
    }
    return $links;
}

// 使用
$html = file_get_contents('https://example.com');
$links = extractLinksDOM($html, 'https://example.com');
print_r($links);
?>

優勢: 正確處理巢狀結構、實體編碼、屬性順序、編碼檢測;可輕鬆擴展提取 title、rel、data-* 等屬性。

進階:過濾與去重

<?php
function filterLinks(array $links, array $allowDomains = [], array $denyPatterns = []) {
    return array_filter($links, function($text, $url) use ($allowDomains, $denyPatterns) {
        // 域名白名單
        if ($allowDomains) {
            $host = parse_url($url, PHP_URL_HOST);
            if (!in_array($host, $allowDomains)) return false;
        }
        // 黑名單模式(正則)
        foreach ($denyPatterns as $pattern) {
            if (preg_match($pattern, $url)) return false;
        }
        return true;
    }, ARRAY_FILTER_USE_BOTH);
}

// 去重(保留首次出現文本)
$uniqueLinks = array_unique($links); // 鍵為 URL 自動去重
?>

相對路徑轉絕對路徑工具函數

<?php
function resolveUrl($base, $relative) {
    if (preg_match('/^[a-z]+:/i', $relative)) return $relative; // 已是絕對
    if ($relative[0] === '/') {
        // 根相對路徑
        $parts = parse_url($base);
        return $parts['scheme'] . '://' . $parts['host'] . $relative;
    }
    // 當前目錄相對
    $baseDir = preg_replace('#/[^/]*$#', '', $base);
    return $baseDir . '/' . $relative;
}
?>

總結

  • 簡單、結構固定、性能敏感:正則
  • 通用網頁、容錯率要求高、需擴展屬性:DOMDocument
  • 大規模爬蟲建議使用 symfony/dom-crawler 或 paquettg/php-html-parser 等成熟庫
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved