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

PHP 爬取網頁所有連結:fopen + 正則解析 href 實作

     編輯:PHP 相關知識

實作原理

  1. fopen() 開啟遠端 URL 串流(需 allow_url_fopen=On)
  2. fread() 循環讀取全部 HTML 內容
  3. 正則表達式匹配所有 href 屬性值
  4. 判斷相對/絕對路徑,補全為完整 URL

核心代碼

<?php
$url = isset($_GET['url']) ? $_GET['url'] : "https://www.csdn.net/expert/";

// 解析基礎 URL
$site = substr($url, 0, strpos($url, "/", 8));           // https://domain.com
$base = substr($url, 0, strrpos($url, "/") + 1);         // https://domain.com/path/

// 讀取遠端內容
$fp = fopen($url, "r");
$contents = '';
while (!feof($fp)) {
    $contents .= fread($fp, 1024);
}
fclose($fp);

// 正則匹配所有 href
$pattern = '|href=["\']?([^"\'>\s]+)["\']?|U';
preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);

// 處理並輸出
foreach ($matches as $i => $m) {
    $link = $m[1];
    if (!preg_match('|://|', $link)) {          // 相對路徑
        if (substr($link, 0, 1) === '/') {      // 站內絕對路徑 /path
            $link = $site . $link;
        } else {                                // 相對路徑 path/file
            $link = $base . $link;
        }
    }
    echo "Link " . ($i+1) . ": $link<br>";
}
?>

正則表達式解析

|href=["\']?([^"\'>\s]+)["\']?|U
|            定界符
 href=       字面匹配
 ["\']?      可選單雙引號
 (           捕獲組開始
   [^"\'>\s]+  非引號、非>、非空白字元(連結內容)
 )           捕獲組結束
 ["\']?      可選結尾引號
 |U          非貪婪模式

功能擴充建議

現代化重寫:Guzzle + Symfony DomCrawler

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

use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;

$client = new Client(['timeout' => 10, 'headers' => ['User-Agent' => 'Mozilla/5.0']]);
$url = 'https://example.com';

try {
    $response = $client->get($url);
    $html = $response->getBody()->getContents();
    
    $crawler = new Crawler($html);
    $links = $crawler->filter('a[href]')->each(function (Crawler $node) use ($url) {
        $href = $node->attr('href');
        // 解析相對路徑
        $absolute = (parse_url($href, PHP_URL_SCHEME)) ? $href : rtrim($url, '/') . '/' . ltrim($href, '/');
        return ['text' => trim($node->text()), 'url' => $absolute];
    });
    
    print_r($links);
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>

法律與道德提醒

  • 遵守目標網站 robots.txt 與服務條款
  • 控制抓取頻率(建議 > 1 秒/請求),避免造成服務負擔
  • 僅抓取公開資料,勿繞過登入/驗證機制
  • 尊重著作權,抓取資料僅供個人研究/分析,不可商業轉售

總結

基於 fopen + 正則的連結提取器構思簡單、零依賴,適合學習 HTTP、正則、URL 解析基礎。生產級爬蟲請採用 Guzzle + DomCrawler 或 Scrapy (Python) 等成熟框架,具備併發、重試、中介軟體、選擇器、管道等企業級能力。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
功能實作方向
遞迴爬取隊列 + 已訪問集合,限制深度/網域
過濾資源類型副檔名判斷、Content-Type 檢查
處理 JS 動態渲染Headless Chrome (Puppeteer/PHP-WebDriver)
反爬蟲應對User-Agent 偽裝、Cookie 池、IP 代理、延遲請求
robots.txt 遵守解析 robots.txt、檢查 User-agent: * 規則
編碼自動偵測mb_detect_encoding() + iconv() 統一轉 UTF-8
儲存資料庫URL、標題、內容摘要、抓取時間、狀態碼