本文展示一個完整的 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")。
CURLOPT_COOKIEJAR/FILE 維持會話,應對需登錄的圖片get_unique() 保證高併發下文件名唯一fopen($name, 'wb') 確保圖片不損壞$img->getAttribute('src')parse_url($baseUrl) 處理 //、/、./ 等相對路徑curl_multi_* 或 GuzzleHttp\Pool 並發請求sleep() / usleep() 控制請求頻率,遵守 robots.txtfunction 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); // 自行實現相對轉絕對
// 下載邏輯...
}
}