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

PHP 正則表達式批量下載網頁圖片到本地實現代碼

     編輯:PHP 綜合知識

PHP 爬蟲實戰:正則提取圖片鏈接並使用 cURL 下載保存

本文展示一個完整的 PHP 腳本,通過 cURL 獲取網頁內容,使用正則表達式提取 <img> 標簽的 src 屬性,再逐一下載圖片到本地。代碼包含去重命名、錯誤處理、Cookie 支持等實用細節。

完整實現代碼

<?php
/**
 * 批量下載網頁圖片
 * @author ssh_kobe
 * @date 2011-06-02
 * @limitation 僅支援絕對路徑圖片,相對路徑需自行補全
 */
set_time_limit(0);  // 移除執行時間限制

$URL = 'https://pp.baidu.com/';  // 目標網址
get_pic($URL);

function get_pic($pic_url) {
    // 1. 獲取網頁二進制內容
    $data = CurlGet($pic_url);
    
    // 2. 正則提取所有 img 標簽的 src
    // 匹配  或 ,捕獲 gif/jpg 路徑
    $pattern_src = '/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/';
    $num = preg_match_all($pattern_src, $data, $match_src);
    $arr_src = $match_src[1];  // 提取捕獲組 1
    
    get_name($arr_src);
    echo "<br>finished!!!";
    return 0;
}

function get_name($pic_arr) {
    // 匹配圖片副檔名
    $pattern_type = '/(/.(jpg|bmp|jpeg|gif|png))/';
    
    foreach ($pic_arr as $pic_item) {
        $num = preg_match_all($pattern_type, $pic_item, $match_type);
        if (!$num) continue;  // 無副檔名跳過
        
        // 微秒時間戳命名,避免重名
        $pic_name = get_unique() . $match_type[1][0];
        
        // 以二進制流寫入文件
        $write_fd = @fopen($pic_name, "wb");
        if ($write_fd) {
            @fwrite($write_fd, CurlGet($pic_item));
            @fclose($write_fd);
            echo "[OK]..!";
        } else {
            echo "[FAIL] 無法寫入 $pic_name";
        }
    }
    return 0;
}

// 微秒級唯一 ID
function get_unique() {
    list($msec, $sec) = explode(" ", microtime());
    return $sec . intval($msec * 1000000);
}

// cURL 獲取遠程內容(支援 Cookie、User-Agent、重定向)
function CurlGet($url) {
    $url = str_replace('&', '&', $url);
    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL            => $url,
        CURLOPT_HEADER         => false,
        CURLOPT_USERAGENT      => "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
        CURLOPT_COOKIEJAR      => 'cookie.txt',  // 保存 Cookie
        CURLOPT_COOKIEFILE     => 'cookie.txt',  // 發送 Cookie
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_FOLLOWLOCATION => 0,  // 不自動跟隨重定向
        CURLOPT_TIMEOUT        => 30,
    ]);
    $values = curl_exec($curl);
    curl_close($curl);
    return $values;
}
?>

正則表達式深度解析

$pattern_src = '/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/';
片段含義
<[img|IMG]匹配 <img 或 <IMG(大小寫兼容)
.*?非貪婪匹配任意字符(除換行)
src=[\'|\"]匹配 src=" 或 src='
(.*?(?:[\.gif|\.jpg]))捕獲組 1:非貪婪匹配以 .gif/.jpg 結尾的路徑
[\'|\"]匹配結束引號
.*?[\/]?>匹配到標簽閉合 > 或 />
⚠️ 缺陷:該正則不支援 .png、.jpeg、.webp 等格式,且無法處理相對路徑(如 src="/images/logo.png" 或 src="images/logo.png")。

關鍵功能點

  • Cookie 持久化:CURLOPT_COOKIEJAR/FILE 維持會話,應對需登錄的圖片
  • 偽裝 User-Agent:模擬 IE 6 避免簡單反爬
  • 微秒命名:get_unique() 保證高併發下文件名唯一
  • 二進制寫入:fopen($name, 'wb') 確保圖片不損壞

生產級改進建議

  1. 使用 DOMDocument 替代正則:HTML 解析器更健壯,支援相對路徑自動補全 $img->getAttribute('src')
  2. 相對路徑轉絕對:結合 parse_url($baseUrl) 處理 //、/、./ 等相對路徑
  3. 並發下載:使用 curl_multi_* 或 GuzzleHttp\Pool 並發請求
  4. 去重機制:URL 去重 + 內容哈希(MD5/感知哈希)去重
  5. 異常處理:捕獲 cURL 錯誤碼、HTTP 狀態碼、寫入失敗,記錄日誌
  6. 限流與禮貌:sleep() / usleep() 控制請求頻率,遵守 robots.txt

現代化重構片段(DOMDocument 版)

function get_pic_dom($url) {
    $html = CurlGet($url);
    $dom = new DOMDocument();
    @$dom->loadHTML($html);  // 抑制 HTML5 解析警告
    $xpath = new DOMXPath($dom);
    $imgs = $xpath->query('//img/@src');
    
    $base = parse_url($url, PHP_URL_SCHEME) . '://' . parse_url($url, PHP_URL_HOST);
    foreach ($imgs as $img) {
        $src = $img->nodeValue;
        $absUrl = make_absolute_url($src, $base);  // 自行實現相對轉絕對
        // 下載邏輯...
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved