PHP+Ajax遠程圖片抓取器下載的例子

來源:互聯網
上載者:User

先看效果


實現原理

發送請求 :將輸入的目標網址及儲存路徑名稱採用AJAX非同步方式發送到image.info.php檔案,該檔案中包含有一個ImageCatch類,注意:因為有一個是指定靶心圖表片抓取,一個是只要指定一個網址,如http://www.111cn.net形式,所以還要有一個參數用來判斷是指定目標抓取還是指定網站抓取。

接收請求 :接收發送過來的兩個參數,目標網址及儲存路徑,執行個體化ImageCatch類,將地址及儲存路徑傳進去,用file_get_contents函數將目標地址的內容讀取賦值給一個變數$content。

先說指定圖片抓取的實現 :指定圖片抓取的方法實現比較簡單,直接用file_get_contents函數將圖片讀取到,再用file_put_contents寫入到一個檔案儲存起來就可以了。

指定網址抓取圖片的實現

方法跟指定圖片地址抓取就有點不一樣了,因為採用的是jquery+ajax無重新整理模式抓取,所以,請求要一次一次發,先說第一次發什麼請求,很顯然,第一次發的請求內容是擷取目標網址的所有圖片地址及圖片總數,那要怎樣擷取目標網址的所有圖片地址呢?思路跟上面的一樣,但方法不同;

第一步:用file_get_contents函數讀取目標網址賦值給一個content變數。

第二步:用正則匹配所有img標籤裡的src屬性,並儲存在一個數組,這樣網頁的圖片地址就已經拿到了

第三步:用正則匹配所有樣式表檔案link標籤的href屬性,並儲存在一個數組$arr1

第四步:還是用file_get_contents函數讀取擷取的樣式表檔案,再用正則去匹配到css樣式裡的url背景圖片地址,並儲存在一個數組$arr2,這樣css樣式的圖片又拿到了

第五步:將$arr1和$arr2用array_merge函數進行合并成$arr,再用一個數組$arr3(‘total’=>count($arr))得出圖片總數並追加到數組$arr裡面去,這樣圖片地址和總數都拿到了

第六步:用json_encode編譯一個返回json資料 第七步:接收返回回來的json資料,將資料都存入一個數組,判斷是否數組為空白,不為空白,則用函數遞迴的方法調用一個函數,每調用一次,在返回結果後就將該數組的第一個元素去掉,再判斷數組是否為空白,不為空白,則繼續發送抓取請求,直到數組為空白,全部圖片就已經都抓取完畢。

好了現在看例子

index.php

 代碼如下 複製代碼
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP遠程圖片抓取</title>
<style>
body { margin:0; padding:0; }
#content { width:90%; height:auto; margin:0 auto; margin-top:20px; font-size:12px; color:#333; }
#content .h1 { width:100%; line-height:30px; text-align:left; }
#content .h2 { width:100%; line-height:30px; text-align:left; }
#content .Schedule { width:auto; height:12px; margin:15px 0px; display:none; background:url() }
#content ul { width:100%; height:auto; margin-top:10px; }
#content ul li { height:24px; line-height:24px;}
#content font { color:#f00; }
</style>
<script type="text/javascript" src="js/jquery.js"></script>
<script>
$(document).ready(function() {
    var TargetUrl;
 var Save;
 function error(info) {
  $('#content .h2 font').text(info);
 }
 function statusInfo(info) {
  $('#content ul').append('<li>'+info+'</li>');
 }
 //禁用按鈕
 function start_d() {
  $('#Single,#more').attr('disabled','disabled');
 }
 //解放按鈕
 function start_s() {
  $('#Single,#more').removeProp('disabled');
 }
 //進度跳轉
 function href() {
  location.href='#bottom';
 }
 //單個圖片抓取
 $('#content .h1 #Single').click(function() {
  TargetUrl=$('#content .h2 .TargetUrl').val();
  Save=$('#content .h2 .Save').val();
  if (TargetUrl=='') {
   error(' * 請填寫目標網址');
   return;
  }
  if (Save=='') {
   error(' * 請填寫儲存目錄');
   return;
  }
  var zurl=new Array(TargetUrl);
  start_d();
  Crawl(zurl,Save);
 });
 function Crawl(zurl,Save) {
  start_d();
  $('#content .Schedule').show();
  if (zurl.length>0) {
   var curl=zurl[0];
  $.ajax({
   url:'image.info.php?Single=Single',
   dataType:'json',
   type:'POST',
   data:'TargetUrl='+curl+'&Save='+Save,
   success: function(data) {
    if (data.status=='ok') {
     statusInfo('遠程圖片 <font>'+curl+'</font> 抓取成功 已儲存在 <font>'+data.FileSave+'</font> 檔案大小:<font>'+data.FileSize+'</font>');
     zurl.shift();  //刪除第一個數組元素並返回
     Crawl(zurl,Save); //使用函數遞迴
     href();
    }else {
     zurl.shift();    //刪除第一個數組元素並返回
     Crawl(zurl,Save); //使用函數遞迴
     statusInfo(data.status);  //顯示失敗資訊
     $('#content .Schedule').hide(); //隱藏LOADING圖片
     start_s();   //按鈕啟用
     href();
    }
   }
  });
  }else {
   $('#content .Schedule').hide();
   statusInfo('圖片抓取完畢');
   start_s();
   href();
  }
 }
 //多個圖片抓取
 $('#content .h1 #more').click(function() {
  TargetUrl=$('#content .h2 .TargetUrl').val();
  Save=$('#content .h2 .Save').val();
  if (TargetUrl=='') {
   error(' * 請填寫目標網址');
   return;
  }
  var str=/^(https?://)?([da-z.-]+).([a-z.]{2,6})([/w .-]*)*/?$/;
  if (!str.test(TargetUrl)) {
   error(' * 目標網址不正確');
   return;
  }
  if (Save=='') {
   error(' * 請填寫儲存目錄');
   return;
  }
  start_d();
  $('#content .Schedule').show();
  $.ajax({
   url:'image.info.php?more=more',
   dataType:'json',
   type:'POST',
   data:'TargetUrl='+TargetUrl+'&Save='+Save,
   success: function(data) {
    if (data[0]!='no') {
     statusInfo('在目標網址 <font>'+TargetUrl+'</font> 找到 <font>'+data['total']+'</font> 張圖片,現進行中抓取....');
     var zurl=new Array();
     for (i=0; i<data['total']; i++) {
      zurl.push(data[i]);
     }
     Crawl(zurl,Save);
    }else {
     statusInfo("未抓取找到任何圖片");
     $('#content .Schedule').hide();
     start_s();
    }
   }
  });
 });
 $('#clear').click(function() {
  $('#content ul li').remove();
 });
});
</script>
</head>
<body>
<div id="content">
 <h1>PHP遠程圖片抓取程式</h1>
 <div class="h1">
    指定圖片抓取:<input type="button" value=" 開始抓取 " id="Single" /> <font>目標網址如:http://www.111cn.Net/123.jpg</font>  指定網址抓取:<input type="button" value=" 開始抓取 " id="more" /> <font>目標網址如:http://www.111cn.Net</font>  <input type="button" value=" 清空狀態資訊 " id="clear" />
    </div>
    <div class="Schedule"><font>正在抓取,請稍後...</font> <img src="loading.gif" border="0" /></div>
    <div class="h2">目標網址:<input type="text" class="TargetUrl" size="40" /> 儲存地址:<input type="text" class="Save" /><font></font></div>
    <ul>
    </ul>
    <a name="bottom"></a>
</div>
</body>
</html>

images.info.php

 代碼如下 複製代碼

<?php
header('Content-Type; text/json; charset=utf-8');
$Single=$_GET['Single'];
$more=$_GET['more'];
$TargetUrl=$_POST['TargetUrl'];
$Save=$_POST['Save'];
//判斷是抓取單個圖片還是多個圖片
if ($Single=='Single') {
 $ImageCatch=new ImageCatch($TargetUrl,$Save);
 $ImageCatch->S();
}else if ($more=='more') {
 $ImageCatch=new ImageCatch($TargetUrl,$Save);
 $ImageCatch->M();
}
//圖片抓取類
class ImageCatch {
 private $TargetUrl;  //目標地址
 private $Save;  //儲存地址
 private $FileName; //檔案名稱及路徑
 private $Type;  //檔案類型
 private $Size;  //檔案大小
 //建構函式
 public function __construct($TargetUrl,$Save) {
  $this->TargetUrl=str_replace("'",'',$TargetUrl);   //去掉單引號
  $this->Save=$Save;
 }
 //CSS樣式表中圖片抓取方法
 public function CSS() {
  $content=@file_get_contents($this->TargetUrl);
  //CSS圖片過濾
  preg_match_all('/<link.+href="?(.*?.css)"?.+>/i',$content,$css);
  $css[1]=array_unique($css[1]);//移除重複的值
  $match2=array();
  if (count($css[1])>0) {
   foreach($css[1] as $val) {
    if (!preg_match('/^(https?://)/i',$val)) {
     $val=$this->TargetUrl.'/'.$val;
     $csscontent=@file_get_contents($val);
    }else {
     $csscontent=@file_get_contents($val);
    }
    //匹配圖片URL地址
    preg_match_all('/url((.*))/i',$csscontent,$cssimg);
    $cssimg[1]=array_unique($cssimg[1]);//移除重複的值
   }   
   foreach($cssimg[1] as $val) {
    //去除 " ) 字元
    $val=preg_replace(array('/"|)/'),'',$val);
    //去除../字元
    $val=str_replace('../','',$val);
    //檢查是否是http://開頭,如果不是則加上要抓取的網址
    if (!preg_match('/^(https?://)/i',$val)) {
     array_push($match2,$this->TargetUrl.'/'.$val);
    }else {
     array_push($match2,$val);
    }
   }
   return $match2;
  }
 }
 //計算並返回圖片數量及地址
 public function M() {
  $content=@file_get_contents($this->TargetUrl);
  //網頁圖片過濾
  $str='/<img.+src="?(.+.(jpg|gif|bmp|bnp|png))"?.+>/i';
  preg_match_all($str,$content,$res);
  if ($res[1]) {
   $res[1]=array_unique($res[1]);//移除重複的值
   $httpstr='/^(https?://)/i';
   $match=array();
   foreach($res[1] as $val) {
    if (!preg_match($httpstr,$val)) {
     array_push($match,$this->TargetUrl.'/'.$val);
    }else {
     array_push($match,$val);
    }
   }
   $cssimg=$this->CSS();
   //掃描出css檔案圖片的總數與網頁圖片相加得到總數
   $total=array("total"=>count($match)+count($cssimg));
   $result=array_merge($total,$match,$cssimg);
   //返回JSON資料
   echo json_encode($result);
  }else {
   $res=array('no');
   echo json_encode($res);
  }
  exit;
 }
 //抓取並儲存圖片
 public function S() {
  $this->Type=substr(strrchr($this->TargetUrl,'.'),1);
  $this->FileName=$this->Save.'/'.substr(strrchr($this->TargetUrl,'/'),1);
  $this->imageType();
  $content=@file_get_contents($this->TargetUrl);
  $this->imageDir();
  if (!@file_put_contents($this->FileName,$content,FILE_USE_INCLUDE_PATH)) {
   @unlink($this->FileName);
   exit('{"status":"沒有找到 '.$this->TargetUrl.' 圖片"}');
  }else {
   $this->imageSize();
   exit('{"status":"ok","FileSave":"'.$this->FileName.'","FileSize":"'.$this->Size.'"}');
  }
 }
 //建立目錄
 private function imageDir() {
  if (!@file_exists($this->Save)) {
   if (!@mkdir($this->Save,0700)) {
    exit('{"status":"建立儲存目錄失敗"}');
   }
  }
 }
 //檔案類型判斷
 private function imageType() {
  $typeArr=array('jpg','png','gif','zip','rar');
  if (!in_array($this->Type,$typeArr)) {
   exit('{"status":"要執行抓取的副檔名有錯誤,'.$this->TargetUrl.'"}');
  }
 }
 //檔案大小檢測
 private function imageSize() {
  if (file_exists($this->FileName)) {
   $this->Size=filesize($this->FileName);
   if ($this->Size>1024*1024*1024) {
    $this->Size=round($this->Size/1024/1024/1024,2).' GB';
   }else if ($this->Size>1024*1024) {
    $this->Size=round($this->Size/1024/1024,2).' MB';
   }else if ($this->Size>1024) {
    $this->Size=$this->Size/1024;
    $this->Size=ceil($this->Size).'KB';
   }else {
    $this->Size=$this->Size.'bit';
   }
  }else {
   return '未找到檔案';
  }
 }
}
?>

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.