发送请求:将输入的目标网址及保存路径名称采用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代码如下:
- <!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();
- 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?:
- 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:
- </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;
- }
-
- public function CSS() {
- $content=@file_get_contents($this->TargetUrl);
-
- 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);
- }
-
- 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);
-
- 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();
-
- $total=array("total"=>count($match)+count($cssimg));
- $result=array_merge($total,$match,$cssimg);
-
- 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 '未找到文件';
- }
- }
- }
- ?>
|