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 '未找到文件';
  }
 }
}
?>

时间: 2024-09-21 05:31:47

PHP+Ajax远程图片抓取器下载的例子的相关文章

一个PHP的远程图片抓取函数分享_php技巧

复制代码 代码如下: function grabImage($url, $filename = '') { if($url == '') { return false; //如果 $url 为空则返回 false; } $ext_name = strrchr($url, '.'); //获取图片的扩展名 if($ext_name != '.gif' && $ext_name != '.jpg' && $ext_name != '.bmp' && $ext_n

构建一个高性能的网页抓取器,互联网营销

  互联网的发展,使人类提前进入了信息爆炸的年代,在浩瀚无边的信息海洋里,如何快速.准确找到对自己有用的信息,就成了一个很有价值的研究课题,于是,搜索引擎应运而生.现在,国内外大大小小的搜索引擎有很多,搜搜也是这搜索引擎大军中的一员悍将.笔者有幸参与了搜搜研发过程中的一些工作,在这里写一些自己的理解与看法,权当是抛砖引玉,希望能够得到业内前辈们的一些指点. 对于网页搜索引擎来说,它的基本处理流程,通常可以分为三个步骤:一是对海量互联网网页的抓取,也称下载:二是对已下载的网页进行预处理,包括抽取正

Linux抓取批量下载地址

视频网站在线播放列表如下图所示: 查看源代码:   <div class="fj1"><span>第1集</span> <a href="/eschool/video/autohtml/310/261/0.shtml" target="_blank">1 C++简介</a></div> <div class="fj1"><span>

PHP通过CURL实现定时任务的图片抓取功能示例_php技巧

本文实例讲述了PHP通过CURL实现定时任务的图片抓取功能.分享给大家供大家参考,具体如下: 下文为各位介绍一个PHP定时任务通过CURL图片的抓取例子,希望例子对大家帮助,基本思路就是通过一个URL连接,将所有图片的地址抓取下来,然后循环打开图片,利用文件操作函数下载下来,保存到本地,并且把图片的alt属性也抓取下来,最后将数据保存到自己数据库. 废话不多说,看程序就能明白了,其中,需要用到PHP定时任务和PHP的一个第三方插件simple_html_dom.php 的使用,参考simple_

ruby实现网页图片抓取_ruby专题

前段时间看到很多人写的下妹子脚本,自己也写一个 module CommonHelper require 'nokogiri' require 'open-uri' def down_load_xmz site_url = "http://www.xxx.com" for index_page in 1..141 doc_html = Nokogiri::HTML(open(site_url+'/share/comment-page-'+index_page.to_s)) doc_htm

软件-java 抓取 网址 下载 图标 版本号

问题描述 java 抓取 网址 下载 图标 版本号 能不能通过一个网站地址获取我要下载的软件的下载地址,软件版本号,和软件的图标 桶过java实现

c c++-抓取迅雷下载的数据包特征

问题描述 抓取迅雷下载的数据包特征 通过抓取迅雷下载时的数据包分析出流量和五元组.可是迅雷的数据包据说是加密的,不能通过数据包特征判断,那么请问还有什么办法找出那些数据包是属于迅雷的.只要找出迅雷的数据包计算流量就行,不是禁用迅雷下载.本人新手,谢谢各位大神赐教啊!

远程控制-我要做一个远程日志抓取程序

问题描述 我要做一个远程日志抓取程序 我要做一个远程日志抓取程序,有没有哪位可以给我个方案,大概百十台服务器,ubuntu系统,在一台机器上执行程序抓其他所有机器上符合条件的日志 解决方案 http://blog.csdn.net/hljlzc2007/article/details/17411185 解决方案二: http://www.cnblogs.com/brucewoo/archive/2011/12/13/2285482.html 解决方案三: 通过syslog来管理 [http://

ruby实现网页图片抓取

  本文给大家分享的是个人使用ruby编写的抓取网页图片的代码,十分的简单实用,有需要的小伙伴可以参考下. 前段时间看到很多人写的下妹子脚本,自己也写一个 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 module CommonHelper   require 'nokogiri' require 'open-uri'   def down_load_xmz sit