PHP批量采集下載美女圖片的實(shí)現(xiàn)代碼
更新時(shí)間:2013年06月03日 17:02:32 作者:
最近在瀏覽某個(gè)美女網(wǎng)站,但是考慮到網(wǎng)速問題,這種網(wǎng)站打開速度慢,廣告多,隨機(jī)想到使用php采集一下這些美女圖片
設(shè)計(jì)思路
考慮到單純的采集一個(gè)網(wǎng)頁的圖片,太麻煩,所以直接采集他的列表頁,獲取列表的url然后在一一采集,但是用php匹配列表頁的url太麻煩,第一列表頁有很多無效url這對(duì)我這個(gè)正則小菜鳥實(shí)在是個(gè)問題,看了一下列表頁的結(jié)構(gòu),果斷采用jquery獲取url,jquery的萬能選擇器又再次強(qiáng)大起來了。
jquery獲取url,然后ajax傳遞url—>對(duì)應(yīng)PHP文件,遍歷url參數(shù)—->單頁面采集保存圖片
jquery程序
<script src="http://www.cztv.com/uibase/jquery.js"></script>
<script >
$(document).ready(function(){
var hrefs ='';
$('.f_folder>a').each(function(i){
var href = $('.f_folder:eq('+i+')>a:eq(0)').attr('href');
if(href!='undefined'){
hrefs +=href+',';
}
})
$.getJSON("http://www.****.com/365/getimg.php?hrefs="+hrefs+"&callback=?", function(data){
//alert(data.info);
});
});
</script>
這里把url拼接成‘,'分割的字符串傳遞url,使用getjson是為了跨域需要,關(guān)于getjson常見的幾個(gè)問題可以參看<$.getjson遇到的幾個(gè)問題>
PHP采集程序
<?php
// 抓起365圖片
error_reporting(E_ALL ^ E_NOTICE);
set_time_limit(0);//設(shè)置PHP超時(shí)時(shí)間
/**
* 得到當(dāng)前時(shí)間
*/
function getMicrotime() {
list ($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
$stime = getMicrotime();
$callback = $_GET['callback'];
$hrefs = $_GET['hrefs'];
$urlarray = explode(',',$hrefs);
//獲取指定url的所有圖片
function getimgs($url){
$dirname = basename($url,".php");
if(!file_exists($dirname)){
mkdir('365/'.$dirname.'');
}
clearstatcache();
$data = file_get_contents($url);
preg_match_all("/(href|src)=(["|']?)([^ "'>]+.(jpg|png|PNG|JPG|gif))\2/i", $data, $matches);
//$matches[3] = array_unique($matches[3]);
unset($data);
$i=0;
if(count($matches[3])>0){
foreach($matches[3] as $k=>$v){
//簡(jiǎn)單判斷是否是標(biāo)準(zhǔn)url,而不是相對(duì)路徑
if(substr($v,0,4)=='http'){
$ext = pathinfo($v,PATHINFO_EXTENSION);//圖片擴(kuò)展
if(!file_exists('365/'.$dirname.'/'.$k.'.'.$ext)){
file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
$i++;
}else{
unset($v);
}
clearstatcache();
}else{
unset($v);
}
}
unset($matches);
return $i;
}
}
foreach($urlarray as $k=>$v){
if($v!=''){
$j +=getimgs($v);
}
}
$etime = getMicrotime();
echo "合計(jì)采集了".$j."張圖片";
echo "用時(shí)".($etime-$stime)."秒";
考慮到性能問題:在getimgs方法中所用的變量都是使用后便注銷(unset)了,以便釋放內(nèi)存。
設(shè)計(jì)到的幾個(gè)知識(shí)點(diǎn)
判斷是否是標(biāo)準(zhǔn)有效圖片url
if(substr($v,0,4)=='http')這個(gè)只是簡(jiǎn)單的判斷一下匹配到的圖片url是否是標(biāo)準(zhǔn)的url,因?yàn)椴杉膱D片可能是相對(duì)路徑的,這里我直接放棄這種圖片的采集,當(dāng)然你也可以把這種圖片還原成標(biāo)準(zhǔn)圖片路徑,還有一個(gè)問題就是即使是標(biāo)準(zhǔn)url格式,這樣的圖片也未必可以采集,因?yàn)槟悴恢肋@個(gè)圖片是否還有,也許這個(gè)圖片url已經(jīng)無效了,如果你想更嚴(yán)格的判斷這個(gè)圖片url是否真實(shí)有效可以推薦看我之前的《PHP判斷遠(yuǎn)程url是否有效的幾種方法》有三種方法可以驗(yàn)證是否是有效url。
獲取圖片格式
$ext = pathinfo($v,PATHINFO_EXTENSION);//圖片擴(kuò)展
這里使用了pathinfo的方法,總結(jié)有7種方法可以獲取到文件的格式,推薦文章:《PHP判斷圖片格式的七種方法》
下載保存到本地
file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
file_put_contents() 函數(shù)把一個(gè)字符串寫入文件中。
與依次調(diào)用 fopen(),fwrite() 以及 fclose() 功能一樣。
file_get_contents() 函數(shù)把整個(gè)文件讀入一個(gè)字符串中。
因?yàn)榉?wù)器支持file_get_contents,如果服務(wù)器把這個(gè)函數(shù)禁用了,可以使用curl,這個(gè)工具要比file_get_contents更加強(qiáng)大,推薦學(xué)習(xí)《CURL的學(xué)習(xí)和應(yīng)用(附多線程)》,可以使用curl的多線程下載存儲(chǔ),效果更牛逼
清除文件操作緩存
clearstatcache() 函數(shù)清除文件狀態(tài)緩存。clearstatcache() 函數(shù)會(huì)緩存某些函數(shù)的返回信息,以便提供更高的性能。但是有時(shí)候,比如在一個(gè)腳本中多次檢查同一個(gè)文件,而該文件在此腳本執(zhí)行期間有被刪除或修改的危險(xiǎn)時(shí),你需要清除文件狀態(tài)緩存,以便獲得正確的結(jié)果。要做到這一點(diǎn),就需要使用 clearstatcache() 函數(shù)。官方手冊(cè):
程序執(zhí)行時(shí)間計(jì)算
/**
* 得到當(dāng)前時(shí)間
*/
function getMicrotime() {
list ($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
可以參考本博客文章;《獲取php頁面執(zhí)行時(shí)間,數(shù)據(jù)庫讀寫次數(shù),函數(shù)調(diào)用次數(shù)等【THINKPHP】》
最后看一下效果;

409秒采集了214張圖片,大概2秒下載保存了一張圖片,圖片總大小約62M,這樣看來:
一個(gè)小時(shí)60*60可以大約下載1800張美女圖片。
考慮到單純的采集一個(gè)網(wǎng)頁的圖片,太麻煩,所以直接采集他的列表頁,獲取列表的url然后在一一采集,但是用php匹配列表頁的url太麻煩,第一列表頁有很多無效url這對(duì)我這個(gè)正則小菜鳥實(shí)在是個(gè)問題,看了一下列表頁的結(jié)構(gòu),果斷采用jquery獲取url,jquery的萬能選擇器又再次強(qiáng)大起來了。
jquery獲取url,然后ajax傳遞url—>對(duì)應(yīng)PHP文件,遍歷url參數(shù)—->單頁面采集保存圖片
jquery程序
復(fù)制代碼 代碼如下:
<script src="http://www.cztv.com/uibase/jquery.js"></script>
<script >
$(document).ready(function(){
var hrefs ='';
$('.f_folder>a').each(function(i){
var href = $('.f_folder:eq('+i+')>a:eq(0)').attr('href');
if(href!='undefined'){
hrefs +=href+',';
}
})
$.getJSON("http://www.****.com/365/getimg.php?hrefs="+hrefs+"&callback=?", function(data){
//alert(data.info);
});
});
</script>
這里把url拼接成‘,'分割的字符串傳遞url,使用getjson是為了跨域需要,關(guān)于getjson常見的幾個(gè)問題可以參看<$.getjson遇到的幾個(gè)問題>
PHP采集程序
復(fù)制代碼 代碼如下:
<?php
// 抓起365圖片
error_reporting(E_ALL ^ E_NOTICE);
set_time_limit(0);//設(shè)置PHP超時(shí)時(shí)間
/**
* 得到當(dāng)前時(shí)間
*/
function getMicrotime() {
list ($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
$stime = getMicrotime();
$callback = $_GET['callback'];
$hrefs = $_GET['hrefs'];
$urlarray = explode(',',$hrefs);
//獲取指定url的所有圖片
function getimgs($url){
$dirname = basename($url,".php");
if(!file_exists($dirname)){
mkdir('365/'.$dirname.'');
}
clearstatcache();
$data = file_get_contents($url);
preg_match_all("/(href|src)=(["|']?)([^ "'>]+.(jpg|png|PNG|JPG|gif))\2/i", $data, $matches);
//$matches[3] = array_unique($matches[3]);
unset($data);
$i=0;
if(count($matches[3])>0){
foreach($matches[3] as $k=>$v){
//簡(jiǎn)單判斷是否是標(biāo)準(zhǔn)url,而不是相對(duì)路徑
if(substr($v,0,4)=='http'){
$ext = pathinfo($v,PATHINFO_EXTENSION);//圖片擴(kuò)展
if(!file_exists('365/'.$dirname.'/'.$k.'.'.$ext)){
file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
$i++;
}else{
unset($v);
}
clearstatcache();
}else{
unset($v);
}
}
unset($matches);
return $i;
}
}
foreach($urlarray as $k=>$v){
if($v!=''){
$j +=getimgs($v);
}
}
$etime = getMicrotime();
echo "合計(jì)采集了".$j."張圖片";
echo "用時(shí)".($etime-$stime)."秒";
考慮到性能問題:在getimgs方法中所用的變量都是使用后便注銷(unset)了,以便釋放內(nèi)存。
設(shè)計(jì)到的幾個(gè)知識(shí)點(diǎn)
判斷是否是標(biāo)準(zhǔn)有效圖片url
if(substr($v,0,4)=='http')這個(gè)只是簡(jiǎn)單的判斷一下匹配到的圖片url是否是標(biāo)準(zhǔn)的url,因?yàn)椴杉膱D片可能是相對(duì)路徑的,這里我直接放棄這種圖片的采集,當(dāng)然你也可以把這種圖片還原成標(biāo)準(zhǔn)圖片路徑,還有一個(gè)問題就是即使是標(biāo)準(zhǔn)url格式,這樣的圖片也未必可以采集,因?yàn)槟悴恢肋@個(gè)圖片是否還有,也許這個(gè)圖片url已經(jīng)無效了,如果你想更嚴(yán)格的判斷這個(gè)圖片url是否真實(shí)有效可以推薦看我之前的《PHP判斷遠(yuǎn)程url是否有效的幾種方法》有三種方法可以驗(yàn)證是否是有效url。
獲取圖片格式
$ext = pathinfo($v,PATHINFO_EXTENSION);//圖片擴(kuò)展
這里使用了pathinfo的方法,總結(jié)有7種方法可以獲取到文件的格式,推薦文章:《PHP判斷圖片格式的七種方法》
下載保存到本地
file_put_contents('365/'.$dirname.'/'.$k.'.'.$ext,file_get_contents($v));
file_put_contents() 函數(shù)把一個(gè)字符串寫入文件中。
與依次調(diào)用 fopen(),fwrite() 以及 fclose() 功能一樣。
file_get_contents() 函數(shù)把整個(gè)文件讀入一個(gè)字符串中。
因?yàn)榉?wù)器支持file_get_contents,如果服務(wù)器把這個(gè)函數(shù)禁用了,可以使用curl,這個(gè)工具要比file_get_contents更加強(qiáng)大,推薦學(xué)習(xí)《CURL的學(xué)習(xí)和應(yīng)用(附多線程)》,可以使用curl的多線程下載存儲(chǔ),效果更牛逼
清除文件操作緩存
clearstatcache() 函數(shù)清除文件狀態(tài)緩存。clearstatcache() 函數(shù)會(huì)緩存某些函數(shù)的返回信息,以便提供更高的性能。但是有時(shí)候,比如在一個(gè)腳本中多次檢查同一個(gè)文件,而該文件在此腳本執(zhí)行期間有被刪除或修改的危險(xiǎn)時(shí),你需要清除文件狀態(tài)緩存,以便獲得正確的結(jié)果。要做到這一點(diǎn),就需要使用 clearstatcache() 函數(shù)。官方手冊(cè):
程序執(zhí)行時(shí)間計(jì)算
復(fù)制代碼 代碼如下:
/**
* 得到當(dāng)前時(shí)間
*/
function getMicrotime() {
list ($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
可以參考本博客文章;《獲取php頁面執(zhí)行時(shí)間,數(shù)據(jù)庫讀寫次數(shù),函數(shù)調(diào)用次數(shù)等【THINKPHP】》
最后看一下效果;

409秒采集了214張圖片,大概2秒下載保存了一張圖片,圖片總大小約62M,這樣看來:
一個(gè)小時(shí)60*60可以大約下載1800張美女圖片。
您可能感興趣的文章:
- PHP多線程批量采集下載美女圖片的實(shí)現(xiàn)代碼(續(xù))
- php curl簡(jiǎn)單采集圖片生成base64編碼(并附curl函數(shù)參數(shù)說明)
- PHP CURL采集百度搜尋結(jié)果圖片不顯示問題的解決方法
- php采集內(nèi)容中帶有圖片地址的遠(yuǎn)程圖片并保存的方法
- PHP遠(yuǎn)程采集圖片詳細(xì)教程
- PHP采集類Snoopy抓取圖片實(shí)例
- phpphp圖片采集后按原路徑保存圖片示例
- php采集文章中的圖片獲取替換到本地(實(shí)現(xiàn)代碼)
- PHP 文章中的遠(yuǎn)程圖片采集到本地的代碼
- PHP下載采集圖片到本地的方法詳解【可忽略ssl認(rèn)證】
相關(guān)文章
解決laravel上傳圖片之后,目錄有圖片,但是訪問不到(404)的問題
今天小編就為大家分享一篇解決laravel上傳圖片之后,目錄有圖片,但是訪問不到(404)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10Laravel5.4簡(jiǎn)單實(shí)現(xiàn)app接口Api Token認(rèn)證方法
這篇文章主要介紹了Laravel5.4簡(jiǎn)單實(shí)現(xiàn)app接口Api Token認(rèn)證,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08CodeIgniter中實(shí)現(xiàn)泛域名解析
這篇文章主要介紹了CodeIgniter中實(shí)現(xiàn)泛域名解析的方法,需要的朋友可以參考下2014-07-07Yii2使用小技巧之通過 Composer 添加 FontAwesome 字體資源
前天幫同事改個(gè)十年前的網(wǎng)站 bug,頁面上一堆 include require 不禁讓人抱頭痛哭??吹?V2EX 上的討論說,寫 PHP 不用框架等同于耍流氓。Yii Framework 是我使用了 2 年多的 PHP 框架,器大活好,皮實(shí)耐操。 Yii2 還在 Beta 中,不過不影響拿來預(yù)研。2014-06-06php之XML轉(zhuǎn)數(shù)組函數(shù)的詳解
本篇文章是對(duì)php中的XML轉(zhuǎn)數(shù)組函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06