程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> PHP+Ajax遠程圖片抓取器下載的例子

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

編輯:關於PHP編程

       先看效果

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

      實現原理

      發送請求 :將輸入的目標網址及保存路徑名稱采用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 '未找到文件';
      }
     }
    }
    ?>

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved