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

PHP 采集器開發心得:從遠端抓取到入庫的完整流程與避坑指南

     編輯:PHP 相關知識

采集核心流程

  1. 獲取遠端源碼:file_get_contents()、cURL、fopen()
  2. 解析提取:正則 preg_match_all()、DOMDocument+XPath、QueryList 庫
  3. 去重/清洗/入庫:資料庫唯一鍵、內容過濾、圖片本地化

基礎代碼骨架

<?php
function fetch($url) {
    $ctx = stream_context_create(['http' => ['timeout' => 15, 'user_agent' => 'Mozilla/5.0']]);
    return @file_get_contents($url, false, $ctx);
}

function extract($html, $pattern) {
    preg_match_all($pattern, $html, $matches);
    return $matches[1] ?? [];
}

// 列表頁采集
$listHtml = fetch('https://example.com/list.html');
$detailUrls = extract($listHtml, '/href="([^"]+\.html)"/');

// 詳情頁采集
foreach ($detailUrls as $url) {
    $detailHtml = fetch($url);
    $title = extract($detailHtml, '/

(.*?)<\/h1>/')[0] ?? ''; $content = extract($detailHtml, '/
(.*?)<\/div>/s')[0] ?? ''; // 入庫(PDO 預處理) $stmt = $pdo->prepare('INSERT INTO articles (title, content, source_url) VALUES (?, ?, ?)'); $stmt->execute([$title, $content, $url]); sleep(1); // 禮貌延遲 } ?>

圖片/檔案本地化下載

function downloadAsset($url, $saveDir) {
    if (empty($url)) return false;
    $ext = strtolower(pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION));
    if (!in_array($ext, ['jpg','jpeg','png','gif','webp','swf','mp4'])) return false;

    $filename = md5($url) . '.' . $ext;
    $path = $saveDir . '/' . $filename;

    if (file_exists($path)) return $filename; // 已下載

    $data = @file_get_contents($url);
    if ($data === false) return false;

    file_put_contents($path, $data);
    return $filename;
}

實戰避坑指南(血淚經驗)

坑點現象解決方案
防盜鏈圖片/頁面返回 403設定 Referer 標頭、使用代理 IP、或放棄該站
編碼不一致中文亂碼mb_detect_encoding() + iconv() 統一轉 UTF-8
動態渲染內容在 JS 中、AJAX 載入分析 API 介面、或用 Headless Chrome (Puppeteer/PHP-WebDriver)
頻率限制/IP 封禁連續請求失敗代理池輪換、隨機延遲、模擬真實瀏覽器指紋
頁面結構變更正則失效改用 DOM+XPath、加入選擇器健壯性檢查、監控告警
重複采集資料庫主鍵衝突URL 去重表、內容指紋 (simhash)、INSERT IGNORE/ON DUPLICATE KEY UPDATE
超時/網路抖動腳本中斷重試機制 (指數退避)、隊列化 (Redis/RabbitMQ) + Worker
大量資料記憶體溢出PHP Fatal Error生成器 yield、分批處理、unset() 釋放大變數

架構升級建議

  • 隊列化:生產者 (列表解析) → Redis List/RabbitMQ → 消費者 (詳情解析/入庫)
  • 去重服務:Bloom Filter + Redis Set + 資料庫唯一索引三層防線
  • 監控告警:成功率、耗時、錯誤率、入庫量 Grafana 看板
  • 分散式:多機器協同,共享隊列與去重集合

法律與道德邊界

  • 遵守 robots.txt、網站服務條款
  • 控制頻率,不影響目標站點正常服務
  • 僅采集公開資料,不繞過登入/驗證
  • 尊重版權,必要時聯繫授權
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved