PHP 通過 file_get_contents() / cURL 獲取網頁源碼,配合正則表達式提取圖片 URL、特定 DIV 內容,是數據採集、內容聚合、SEO 分析的基礎技能。本文提供四大核心場景完整代碼,深度解析正則模式設計、編碼轉換、異常處理及反爬蟲應對策略。
file_get_contents()(簡單)、cURL(支持 Header、Cookie、代理、超時控制)preg_match_all()(多匹配)、preg_match()(單匹配)mb_convert_encoding()、iconv() 統一轉 UTF-8DOMDocument + DOMXPath(結構化提取,健壯性優於正則)$url = 'https://www.example.com'; $html = file_get_contents($url); // 正則:匹配標簽,捕獲完整標簽 $pattern = '/
]*>/i'; preg_match_all($pattern, $html, $matches); print_r($matches[0]); /* Array ( [0] =>
[1] =>
... ) */
$pattern = '/]*>/Ui'; // U: 非貪婪模式,i: 忽略大小寫 preg_match($pattern, $html, $match); $firstImgTag = $match[0] ?? ''; // 進階:直接提取 src 屬性值 $srcPattern = '/
]*src=["\']([^"\']+)["\'][^>]*>/i'; preg_match($srcPattern, $html, $srcMatch); $firstImgSrc = $srcMatch[1] ?? ''; // 獲取第一張圖片 URL
// 目標:...$pattern = '/]*id=["\']PostContent["\'][^>]*>(.*?)<\/div>/si'; // s: 單行模式(. 匹配換行),i: 忽略大小寫 preg_match($pattern, $html, $match); $divContent = $match[1] ?? ''; // 獲取內部 HTML(不含外層 div)場景四:組合提取 — 先定位 DIV,再提取其中圖片
$html = file_get_contents($url); // 1. 提取目標 DIV 內容 $divPattern = '/]*id=["\']PostContent["\'][^>]*>(.*?)<\/div>/si'; preg_match($divPattern, $html, $divMatch); $divHtml = $divMatch[1] ?? ''; // 2. 在 DIV 內容中提取圖片 $imgPattern = '/]*src=["\']([^"\']+)["\'][^>]*>/i'; preg_match_all($imgPattern, $divHtml, $imgMatches); $images = $imgMatches[1] ?? []; // 該 DIV 內所有圖片 URL 陣列
關鍵技術難點與解決方案
1. 編碼亂碼:統一轉 UTF-8
$html = file_get_contents($url); // 檢測編碼(從 Content-Type 或 meta 標簽) $encoding = mb_detect_encoding($html, ['UTF-8', 'GBK', 'GB2312', 'BIG5']); if ($encoding && $encoding !== 'UTF-8') { $html = mb_convert_encoding($html, 'UTF-8', $encoding); } // 現在正則匹配中文內容正常2. 相對路徑轉絕對 URL
function toAbsoluteUrl($src, $baseUrl) { if (preg_match('/^https?:\/\//i', $src)) return $src; // 已是絕對 $base = parse_url($baseUrl); $basePath = rtrim(dirname($base['path']), '/') . '/'; if ($src[0] === '/') return $base['scheme'] . '://' . $base['host'] . $src; // 根相對 return $base['scheme'] . '://' . $base['host'] . $basePath . $src; // 相對路徑 } // 使用 $images = array_map(function($src) use ($url) { return toAbsoluteUrl($src, $url); }, $images);3. 防爬蟲應對:偽裝 Header、Cookie、代理
function fetchWithCurl($url, $options = []) { $ch = curl_init($url); $defaults = [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 5, CURLOPT_TIMEOUT => 15, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', CURLOPT_REFERER => 'https://www.google.com/', CURLOPT_HTTPHEADER => [ 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8', 'Accept-Encoding: gzip, deflate, br', 'Connection: keep-alive', ], CURLOPT_ENCODING => 'gzip,deflate', // 自動解壓 CURLOPT_COOKIEJAR => tempnam(sys_get_temp_dir(), 'cookie_'), // 自動管理 Cookie CURLOPT_COOKIEFILE => tempnam(sys_get_temp_dir(), 'cookie_'), ]; curl_setopt_array($ch, array_merge($defaults, $options)); $html = curl_exec($ch); $errno = curl_errno($ch); curl_close($ch); if ($errno) throw new Exception("cURL Error $errno: " . curl_error($ch)); return $html; }4. 正則局限性:推薦 DOMDocument 解析
$dom = new DOMDocument(); libxml_use_internal_errors(true); // 抑制 HTML5 非標準警告 $dom->loadHTML('' . $html); // 強制 UTF-8 解析 libxml_clear_errors(); $xpath = new DOMXPath($dom); // 提取所有圖片 src $imgs = $xpath->query('//img/@src'); $images = []; foreach ($imgs as $img) $images[] = $img->nodeValue; // 提取特定 DIV 內容 $div = $xpath->query('//div[@id="PostContent"]')->item(0); $divContent = $div ? $dom->saveHTML($div) : ''; // 提取 DIV 內圖片 $divImgs = $xpath->query('//div[@id="PostContent"]//img/@src'); $imagesInDiv = []; foreach ($divImgs as $img) $imagesInDiv[] = $img->nodeValue;DOM 解析優勢:自動修正斷裂 HTML、屬性值解碼、結構化查詢、不易因標簽屬性順序變化失效。
法律與道德邊界
- 遵守 robots.txt:檢查
User-agent: * Disallow: /path- 頻率控制:
sleep(rand(1,3))隨機延遲,避免壓垮目標服務器- 版權合規:僅抓取公開數據,商業用途需授權,遵守《計算機信息網絡國際聯網管理暫行規定》等法規
- 數據最小化:僅提取業務必要字段,不濫存用戶隱私數據
總結
PHP 網頁內容提取的核心鏈路:cURL 獲取 → 編碼統一 → DOM/正則提取 → URL 絕對化 → 合規存儲。正則適合簡單、固定結構提取;DOMDocument 適合複雜、變化結構。生產環境建議封裝為可配置的採集器類,集成代理池、瀏覽器指紋輪換、分布式任務隊列,構建穩健合規的數據採集體系。