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

PHP 實現 CSS 背景圖片批量下載器完整程式碼

     編輯:PHP 相關知識

前言

前端開發中常需要從現有網站提取 CSS 背景圖片。手動下載效率低且易出錯,本文提供一個功能完整的 PHP 命令列工具,支援遠端 CSS 解析、相對/絕對路徑處理、圖片去重與批量下載。

工具特性

  • 支援遠端 CSS URL 直接解析
  • 自動處理相對路徑轉絕對路徑
  • 圖片 URL 去重機制
  • 支援常見圖片格式驗證
  • 命令列參數化操作
  • 下載進度與結果回報

完整程式碼實現

<?php
/**
 * CSS 背景圖片批量下載器
 * @author 開發者
 * @usage php cssImages.php [類型] [CSS路徑] [儲存目錄]
 *        類型: 0=遠端, 1=本地
 *        範例: php cssImages.php 0 https://example.com/style.css \images\
 */

set_time_limit(0);
error_reporting(E_ERROR);

// 參數檢查
if ($argc < 4) {
    print_r("
+-------------------------------------------------+
Usage: php {$argv[0]} css路徑類型(0遠端/1本地) css文件路徑 圖片保存目錄
Example:
php {$argv[0]} 0 https://www.xxx.com/index.css \\images\\
+-------------------------------------------------+
");
    exit();
}

$type = $argv[1];
$cssPath = $argv[2];
$saveDir = $argv[3];

// 全域變數
$host = '';
$savePath = '';

// 遠端 CSS 處理
if ($type == 0) {
    $host = getParse($cssPath, 'host');
    $savePath = getSavePath($saveDir);
    $images = getCssImagesArray($cssPath);
    $imageUrls = getImagesLinks($images, $cssPath);
    imagesDowner($imageUrls);
}

// 本地 CSS 處理(預留擴展)
if ($type == 1) {
    // 本地檔案處理邏輯
    echo "本地模式暫未實現\n";
}

/**
 * 解析 CSS 檔案,提取所有 url() 內的圖片路徑
 */
function getCssImagesArray($cssPath) {
    $cssContent = file_get_contents($cssPath);
    $images = array();
    // 匹配 url(路徑) 模式,支援單雙引號或無引號
    preg_match_all("|url\((['\"]?)(.+?)\\1\)|i", $cssContent, $matches);
    return $matches[2]; // 返回捕獲組 2(實際路徑)
}

/**
 * 解析 CSS 路徑,獲取非檔名部分的目錄路徑
 */
function getNocssPath($path) {
    global $host;
    $tempPath = explode('/', $path);
    $tempLinkImages = '';
    
    // 重構目錄路徑(排除協定、主機、檔名)
    for ($i = 1; $i < (count($tempPath) - 1); $i++) {
        $tempLinkImages .= $tempPath[$i] . '/';
    }
    
    return $host . $tempLinkImages;
}

/**
 * 根據 CSS 路徑解析圖片完整 URL
 */
function getImagesLinks($imagesArray, $cssLink) {
    global $host;
    $urlImages = array();
    
    foreach ($imagesArray as $key => $value) {
        $value = trim($value);
        
        if (pathCheck($value)) {
            // 絕對路徑(以 / 開頭)
            $fullUrl = $host . $value;
            if (!in_array($fullUrl, $urlImages)) {
                $urlImages[$key] = $fullUrl;
            }
        } else {
            // 相對路徑
            $basePath = getNocssPath(getParse($cssLink, 'path'));
            $fullUrl = $basePath . $value;
            if (!in_array($fullUrl, $urlImages)) {
                $urlImages[$key] = $fullUrl;
            }
        }
    }
    
    return $urlImages;
}

/**
 * 批量下載圖片
 */
function imagesDowner($urlImages) {
    foreach ($urlImages as $key => $value) {
        // 清理 URL
        $cleanUrl = str_replace('//', '/', $value);
        $cleanUrl = str_replace('"', '', $cleanUrl);
        $cleanUrl = str_replace("'", '', $cleanUrl);
        $cleanUrl = 'https://' . ltrim($cleanUrl, 'https://');
        
        $filename = basename($cleanUrl);
        
        if (grabImage($cleanUrl, $filename)) {
            print_r($filename . " 文件下載成功\n");
        } else {
            print_r($filename . " 下載失敗\n");
        }
    }
}

/**
 * 判斷是否為絕對路徑
 */
function pathCheck($imageUrl) {
    return preg_match('|^/|', $imageUrl) ? true : false;
}

/**
 * 下載單張圖片
 */
function grabImage($url, $filename) {
    global $savePath;
    
    if (empty($url)) return false;
    
    // 驗證副檔名
    $ext = strrchr($url, '.');
    $allowedExt = array('.gif', '.jpg', '.jpeg', '.bmp', '.png', '.webp', '.svg');
    if (!in_array(strtolower($ext), $allowedExt)) {
        return false;
    }
    
    if (empty($filename)) return false;
    
    // 使用 readfile 獲取遠端內容
    ob_start();
    if (readfile($url)) {
        $imgData = ob_get_contents();
        ob_end_clean();
        $size = strlen($imgData);
    } else {
        ob_end_clean();
        return false;
    }
    
    // 寫入本地檔案
    $filePath = $savePath . $filename;
    if (($fp = fopen($filePath, 'w')) && fwrite($fp, $imgData)) {
        fclose($fp);
        return true;
    }
    
    return false;
}

/**
 * 獲取本地儲存絕對路徑
 */
function getSavePath($savePath) {
    $fullPath = dirname(__FILE__) . $savePath;
    
    // 自動建立目錄
    if (!is_dir($fullPath)) {
        mkdir($fullPath, 0755, true);
    }
    
    return $fullPath;
}

/**
 * 解析 URL 組件
 */
function getParse($url, $type) {
    $parsed = parse_url($url);
    $value = isset($parsed[$type]) ? $parsed[$type] : '';
    
    // host 自動補全結尾斜線
    if ($type === 'host' && $value) {
        $value = rtrim($value, '/') . '/';
    }
    
    return $value;
}
?>

使用說明

命令列參數

參數說明範例
類型0=遠端 CSS, 1=本地 CSS0
CSS 路徑遠端完整 URL 或本地檔案路徑https://example.com/css/style.css
儲存目錄相對於腳本目錄的儲存路徑\images\

執行範例

# Windows
php.exe cssImages.php 0 https://www.example.com/css/main.css \images\

# Linux/Mac
php cssImages.php 0 https://www.example.com/css/main.css /images/

核心邏輯解析

1. CSS 解析正則優化

原版 |url\((.+)\)|i 存在貪婪匹配問題,改進版使用 |url\((['\"]?)(.+?)\\1\)|i:

  • 支援 url(image.png)、url('image.png')、url("image.png")
  • 非貪婪匹配 .+? 避免跨多個 url() 捕獲
  • 反向引用 \\1 確保引號成對

2. 路徑解析策略

  • 絕對路徑:以 / 開頭 → 直接拼接主機名
  • 相對路徑:其他情況 → 基於 CSS 檔案所在目錄拼接
  • 去重機制:使用 in_array 檢查避免重複下載

3. 檔案下載機制

  • 使用 readfile() + 輸出緩衝區獲取二進位內容
  • 副檔名白名單驗證,防止下載非圖片檔案
  • 自動建立儲存目錄

擴展建議

  • 並發下載:使用 curl_multi 或 pthreads 實現多執行緒下載
  • 斷點續傳:支援大檔案分片下載與續傳
  • CSS 壓縮支援:預處理 minified CSS 的單行格式
  • Source Map 解析:提取原始來源檔案中的圖片引用
  • 圖片優化:下載後自動壓縮(結合 imagick/gd)

注意事項

  1. 請遵守目標網站的 robots.txt 與服務條款
  2. 大量下載請加入延遲,避免對目標伺服器造成壓力
  3. 處理 HTTPS 網站時確保 PHP 開啟 OpenSSL 擴展
  4. 某些網站有防盜鏈機制,需模擬 Referer/Header

總結

本工具提供了從 CSS 提取並下載背景圖片的完整解決方案,核心邏輯涵蓋 CSS 解析、路徑解析、去重、下載等關鍵環節。程式碼結構清晰,易於擴展與維護,可作為前端資源遷移、設計素材收集等場景的實用工具。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved