当前位置:首页 > PHP教程 > php高级应用 > 列表

PHP+Ajax远程图片抓取器下载的例子

发布:smiling 来源: PHP粉丝网  添加日期:2014-09-22 14:26:12 浏览: 评论:0 

发送请求:将输入的目标网址及保存路径名称采用AJAX异步的方式发送到image.info.php文件,该文件中包含有一个ImageCatch类,注意,因为有一个是指定目标图片抓取,一个是只要指定一个网址,如http://www.phpfensi.com形式,所以还要有一个参数用来判断是指定目标抓取还是指定网站抓取.

接收请求:接收发送过来的两个参数,目标网址及保存路径,实例化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代码如下:

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  2. <html xmlns="http://www.w3.org/1999/xhtml"
  3. <head> 
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  5. <title>PHP远程图片抓取</title> 
  6. <style> 
  7. body { margin:0; padding:0; } 
  8. #content { width:90%; height:auto; margin:0 auto; margin-top:20px; font-size:12px; color:#333; } 
  9. #content .h1 { width:100%; line-height:30px; text-align:left; } 
  10. #content .h2 { width:100%; line-height:30px; text-align:left; } 
  11. #content .Schedule { width:auto; height:12px; margin:15px 0px; display:none; background:url() } 
  12. #content ul { width:100%; height:auto; margin-top:10px; } 
  13. #content ul li { height:24px; line-height:24px;} 
  14. #content font { color:#f00; } 
  15. </style> 
  16. <script type="text/javascript" src="js/jquery.js"></script> 
  17. <script> 
  18. $(document).ready(function() { 
  19.     var TargetUrl; 
  20.  var Save; 
  21.  function error(info) { 
  22.   $('#content .h2 font').text(info); 
  23.  } 
  24.  function statusInfo(info) { 
  25.   $('#content ul').append('<li>'+info+'</li>'); 
  26.  } 
  27.  //禁用按钮 
  28.  function start_d() { 
  29.   $('#Single,#more').attr('disabled','disabled'); 
  30.  } 
  31.  //解放按钮 
  32.  function start_s() { 
  33.   $('#Single,#more').removeProp('disabled'); 
  34.  } 
  35.  //进度跳转 
  36.  function href() { 
  37.   location.href='#bottom'
  38.  } 
  39.  //单个图片抓取 
  40.  $('#content .h1 #Single').click(function() { 
  41.   TargetUrl=$('#content .h2 .TargetUrl').val(); 
  42.   Save=$('#content .h2 .Save').val(); 
  43.   if (TargetUrl=='') { 
  44.    error(' * 请填写目标网址'); 
  45.    return
  46.   } 
  47.   if (Save=='') { 
  48.    error(' * 请填写保存目录'); 
  49.    return
  50.   } 
  51.   var zurl=new Array(TargetUrl); 
  52.   start_d(); 
  53.   Crawl(zurl,Save); 
  54.  }); 
  55.  function Crawl(zurl,Save) { 
  56.   start_d(); 
  57.   $('#content .Schedule').show(); 
  58.   if (zurl.length>0) { 
  59.    var curl=zurl[0]; 
  60.   $.ajax({ 
  61.    url:'image.info.php?Single=Single'
  62.    dataType:'json'
  63.    type:'POST'
  64.    data:'TargetUrl='+curl+'&Save='+Save, 
  65.    success: function(data) { 
  66.     if (data.status=='ok') { 
  67.      statusInfo('远程图片 <font>'+curl+'</font> 抓取成功 已保存在 <font>'+data.FileSave+'</font> 文件大小:<font>'+data.FileSize+'</font>'); 
  68.      zurl.shift();  //删除第一个数组元素并返回 
  69.      Crawl(zurl,Save); //使用函数递归 
  70.      href(); 
  71.     }else { 
  72.      zurl.shift();    //删除第一个数组元素并返回 
  73.      Crawl(zurl,Save); //使用函数递归 
  74.      statusInfo(data.status);  //显示失败信息 
  75.      $('#content .Schedule').hide(); //隐藏LOADING图片 
  76.      start_s();   //按钮启用 
  77.      href(); 
  78.     } 
  79.    } 
  80.   }); 
  81.   }else { 
  82.    $('#content .Schedule').hide(); 
  83.    statusInfo('图片抓取完毕'); 
  84.    start_s(); 
  85.    href(); 
  86.   } 
  87.  } 
  88.  //多个图片抓取 
  89.  $('#content .h1 #more').click(function() { 
  90.   TargetUrl=$('#content .h2 .TargetUrl').val(); 
  91.   Save=$('#content .h2 .Save').val(); 
  92.   if (TargetUrl=='') { 
  93.    error(' * 请填写目标网址'); 
  94.    return
  95.   } 
  96.   var str=/^(https?://)?([da-z.-]+).([a-z.]{2,6})([/w .-]*)*/?$/; 
  97.   if (!str.test(TargetUrl)) { 
  98.    error(' * 目标网址不正确'); 
  99.    return
  100.   } 
  101.   if (Save=='') { 
  102.    error(' * 请填写保存目录'); 
  103.    return
  104.   } 
  105.   start_d(); 
  106.   $('#content .Schedule').show(); 
  107.   $.ajax({ 
  108.    url:'image.info.php?more=more'
  109.    dataType:'json'
  110.    type:'POST'
  111.    data:'TargetUrl='+TargetUrl+'&Save='+Save, 
  112.    success: function(data) { 
  113.     if (data[0]!='no') { 
  114.      statusInfo('在目标网址 <font>'+TargetUrl+'</font> 找到 <font>'+data['total']+'</font> 张图片,现正在进行抓取....'); 
  115.      var zurl=new Array(); 
  116.      for (i=0; i<data['total']; i++) { 
  117.       zurl.push(data[i]); 
  118.      } 
  119.      Crawl(zurl,Save); 
  120.     }else { 
  121.      statusInfo("未抓取找到任何图片"); 
  122.      $('#content .Schedule').hide(); 
  123.      start_s(); 
  124.     } 
  125.    } 
  126.   }); 
  127.  }); 
  128.  $('#clear').click(function() { 
  129.   $('#content ul li').remove(); 
  130.  }); 
  131. }); 
  132. </script> 
  133. </head> 
  134. <body> 
  135. <div id="content"
  136.  <h1>PHP远程图片抓取程序</h1> 
  137.  <div class="h1"
  138.     指定图片抓取:<input type="button" value=" 开始抓取 " id="Single" /> <font>目标网址如:http://www.phpfensi.com/123.jpg</font>  指定网址抓取:<input type="button" value=" 开始抓取 " id="more" /> <font>目标网址如:http://www.phpfensi.com</font>  <input type="button" value=" 清空状态信息 " id="clear" /> 
  139.     </div> 
  140.     <div class="Schedule"><font>正在抓取,请稍后...</font> <img src="loading.gif" border="0" /></div> 
  141.     <div class="h2">目标网址:<input type="text" class="TargetUrl" size="40" /> 保存地址:<input type="text" class="Save" /><font></font></div> 
  142.     <ul> 
  143.     </ul> 
  144.     <a name="bottom"></a> 
  145. </div> 
  146. </body> 
  147. </html>  

images.info.php,代码如下:

  1. <?php 
  2. header('Content-Type; text/json; charset=utf-8'); 
  3. $Single=$_GET['Single']; 
  4. $more=$_GET['more']; 
  5. $TargetUrl=$_POST['TargetUrl']; 
  6. $Save=$_POST['Save']; 
  7. //判断是抓取单个图片还是多个图片 
  8. if ($Single=='Single') { 
  9.  $ImageCatch=new ImageCatch($TargetUrl,$Save); 
  10.  $ImageCatch->S(); 
  11. }else if ($more=='more') { 
  12.  $ImageCatch=new ImageCatch($TargetUrl,$Save); 
  13.  $ImageCatch->M(); 
  14. //图片抓取类 
  15. class ImageCatch { 
  16.  private $TargetUrl;  //目标地址 
  17.  private $Save;  //保存地址 
  18.  private $FileName//文件名称及路径 
  19.  private $Type;  //文件类型 
  20.  private $Size;  //文件大小 
  21.  //构造函数 
  22.  public function __construct($TargetUrl,$Save) { 
  23.   $this->TargetUrl=str_replace("'",'',$TargetUrl);   //去掉单引号 
  24.   $this->Save=$Save
  25.  } 
  26.  //CSS样式表中图片抓取方法 
  27.  public function CSS() { 
  28.   $content=@file_get_contents($this->TargetUrl); 
  29.   //CSS图片过滤 
  30.   preg_match_all('/<link.+href="?(.*?.css)"?.+>/i',$content,$css); 
  31.   $css[1]=array_unique($css[1]);//移除重复的值 
  32.   $match2=array(); 
  33.   if (count($css[1])>0) { 
  34.    foreach($css[1] as $val) { 
  35.     if (!preg_match('/^(https?://)/i',$val)) { 
  36.      $val=$this->TargetUrl.'/'.$val
  37.      $csscontent=@file_get_contents($val); 
  38.     }else { 
  39.      $csscontent=@file_get_contents($val); 
  40.     } 
  41.     //匹配图片URL地址 
  42.     preg_match_all('/url((.*))/i',$csscontent,$cssimg); 
  43.     $cssimg[1]=array_unique($cssimg[1]);//移除重复的值 
  44.    }    
  45.    foreach($cssimg[1] as $val) { 
  46.     //去除 " ) 字符 
  47.     $val=preg_replace(array('/"|)/'),'',$val); 
  48.     //去除../字符 
  49.     $val=str_replace('../','',$val); 
  50.     //检查是否是http://开头,如果不是则加上要抓取的网址 
  51.     if (!preg_match('/^(https?://)/i',$val)) { 
  52.      array_push($match2,$this->TargetUrl.'/'.$val); 
  53.     }else { 
  54.      array_push($match2,$val); 
  55.     } 
  56.    } 
  57.    return $match2
  58.   } 
  59.  } 
  60.  //计算并返回图片数量及地址 
  61.  public function M() { 
  62.   $content=@file_get_contents($this->TargetUrl); 
  63.   //网页图片过滤 
  64.   $str='/<img.+src="?(.+.(jpg|gif|bmp|bnp|png))"?.+>/i'
  65.   preg_match_all($str,$content,$res); 
  66.   if ($res[1]) { 
  67.    $res[1]=array_unique($res[1]);//移除重复的值 
  68.    $httpstr='/^(https?://)/i'
  69.    $match=array(); 
  70.    foreach($res[1] as $val) { 
  71.     if (!preg_match($httpstr,$val)) { 
  72.      array_push($match,$this->TargetUrl.'/'.$val); 
  73.     }else { 
  74.      array_push($match,$val); 
  75.     } 
  76.    } 
  77.    $cssimg=$this->CSS(); 
  78.    //扫描出css文件图片的总数与网页图片相加得到总数 
  79.    $total=array("total"=>count($match)+count($cssimg)); 
  80.    $result=array_merge($total,$match,$cssimg); 
  81.    //返回JSON数据 
  82.    echo json_encode($result); 
  83.   }else { 
  84.    $res=array('no'); 
  85.    echo json_encode($res); 
  86.   } 
  87.   exit
  88.  } 
  89.  //抓取并保存图片 
  90.  public function S() { 
  91.   $this->Type=substr(strrchr($this->TargetUrl,'.'),1); 
  92.   $this->FileName=$this->Save.'/'.substr(strrchr($this->TargetUrl,'/'),1); 
  93.   $this->imageType(); 
  94.   $content=@file_get_contents($this->TargetUrl); 
  95.   $this->imageDir(); 
  96.   if (!@file_put_contents($this->FileName,$content,FILE_USE_INCLUDE_PATH)) { 
  97.    @unlink($this->FileName); 
  98.    exit('{"status":"没有找到 '.$this->TargetUrl.' 图片"}'); 
  99.   }else { 
  100.    $this->imageSize(); 
  101.    exit('{"status":"ok","FileSave":"'.$this->FileName.'","FileSize":"'.$this->Size.'"}'); 
  102.   } 
  103.  } 
  104.  //新建目录 
  105.  private function imageDir() { 
  106.   if (!@file_exists($this->Save)) { 
  107.    if (!@mkdir($this->Save,0700)) { 
  108.     exit('{"status":"新建保存目录失败"}'); 
  109.    } 
  110.   } 
  111.  } 
  112.  //文件类型判断 
  113.  private function imageType() { 
  114.   $typeArr=array('jpg','png','gif','zip','rar'); 
  115.   if (!in_array($this->Type,$typeArr)) { 
  116.    exit('{"status":"要执行抓取的文件扩展名有错误,'.$this->TargetUrl.'"}'); 
  117.   } 
  118.  } 
  119.  //文件大小检测 
  120.  private function imageSize() { 
  121.   if (file_exists($this->FileName)) { 
  122.    $this->Size=filesize($this->FileName); 
  123.    if ($this->Size>1024*1024*1024) { 
  124.     $this->Size=round($this->Size/1024/1024/1024,2).' GB'
  125.    }else if ($this->Size>1024*1024) { 
  126.     $this->Size=round($this->Size/1024/1024,2).' MB'
  127.    }else if ($this->Size>1024) { 
  128.     $this->Size=$this->Size/1024; 
  129.     $this->Size=ceil($this->Size).'KB'
  130.    }else { 
  131.     $this->Size=$this->Size.'bit'
  132.    } 
  133.   }else { 
  134.    return '未找到文件'
  135.   } 
  136.  } 
  137. ?>

Tags: PHP+Ajax PHP远程图片抓取

分享到: