Maison >php教程 >php手册 >PHP+Ajax远程图片抓取器下载的例子

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

WBOY
WBOYoriginal
2016-06-02 09:13:451267parcourir

发送请求:将输入的目标网址及保存路径名称采用AJAX异步的方式发送到image.info.php文件,该文件中包含有一个ImageCatch类,注意,因为有一个是指定目标图片抓取,一个是只要指定一个网址,如http://www.phprm.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> 
<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) {
        $(&#39;#content .h2 font&#39;).text(info);
    }
    function statusInfo(info) {
        $(&#39;#content ul&#39;).append(&#39;<li>&#39; + info + &#39;</li>&#39;);
    }
    //禁用按钮
    function start_d() {
        $(&#39;#Single,#more&#39;).attr(&#39;disabled&#39;, &#39;disabled&#39;);
    }
    //解放按钮
    function start_s() {
        $(&#39;#Single,#more&#39;).removeProp(&#39;disabled&#39;);
    }
    //进度跳转
    function href() {
        location.href = &#39;#bottom&#39;;
    }
    //单个图片抓取
    $(&#39;#content .h1 #Single&#39;).click(function () {
        TargetUrl = $(&#39;#content .h2 .TargetUrl&#39;).val();
        Save = $(&#39;#content .h2 .Save&#39;).val();
        if (TargetUrl == &#39;&#39;) {
            error(&#39; * 请填写目标网址&#39;);
            return;
        }
        if (Save == &#39;&#39;) {
            error(&#39; * 请填写保存目录&#39;);
            return;
        }
        var zurl = new Array(TargetUrl);
        start_d();
        Crawl(zurl, Save);
    });
    function Crawl(zurl, Save) {
        start_d();
        $(&#39;#content .Schedule&#39;).show();
        if (zurl.length > 0) {
            var curl = zurl[0];
            $.ajax({
                url : &#39;image.info.php?Single=Single&#39;,
                dataType : &#39;json&#39;,
                type : &#39;POST&#39;,
                data : &#39;TargetUrl=&#39; + curl + &#39;&Save=&#39; + Save,
                success : function (data) {
                    if (data.status == &#39;ok&#39;) {
                        statusInfo(&#39;远程图片 <font>&#39; + curl + &#39;</font> 抓取成功 已保存在 <font>&#39; + data.FileSave + &#39;</font> 文件大小:<font>&#39; + data.FileSize + &#39;</font>&#39;);
                        zurl.shift(); //删除第一个数组元素并返回
                        Crawl(zurl, Save); //使用函数递归
                        href();
                    } else {
                        zurl.shift(); //删除第一个数组元素并返回
                        Crawl(zurl, Save); //使用函数递归
                        statusInfo(data.status); //显示失败信息
                        $(&#39;#content .Schedule&#39;).hide(); //隐藏LOADING图片
                        start_s(); //按钮启用
                        href();
                    }
                }
            });
        } else {
            $(&#39;#content .Schedule&#39;).hide();
            statusInfo(&#39;图片抓取完毕&#39;);
            start_s();
            href();
        }
    }
    //多个图片抓取
    $(&#39;#content .h1 #more&#39;).click(function () {
        TargetUrl = $(&#39;#content .h2 .TargetUrl&#39;).val();
        Save = $(&#39;#content .h2 .Save&#39;).val();
        if (TargetUrl == &#39;&#39;) {
            error(&#39; * 请填写目标网址&#39;);
            return;
        }
        var str = /^(https?:/ / ) ? ([da - z. - ] + ).([a - z.]{
            2,
            6
        })([/w .-]*)*/ ? $ / ;
                if (!str.test(TargetUrl)) {
                    error(&#39; * 目标网址不正确&#39;);
                    return;
                }
                if (Save == &#39;&#39;) {
                    error(&#39; * 请填写保存目录&#39;);
                    return;
                }
                start_d();
                $(&#39;#content .Schedule&#39;).show();
                $.ajax({
                    url : &#39;image.info.php?more=more&#39;,
                    dataType : &#39;json&#39;,
                    type : &#39;POST&#39;,
                    data : &#39;TargetUrl=&#39; + TargetUrl + &#39;&Save=&#39; + Save,
                    success : function (data) {
                        if (data[0] != &#39;no&#39;) {
                            statusInfo(&#39;在目标网址 <font>&#39; + TargetUrl + &#39;</font> 找到 <font>&#39; + data[&#39;total&#39;] + &#39;</font> 张图片,现正在进行抓取....&#39;);
                            var zurl = new Array();
                            for (i = 0; i < data[&#39;total&#39;]; i++) {
                                zurl.push(data[i]);
                            }
                            Crawl(zurl, Save);
                        } else {
                            statusInfo("未抓取找到任何图片");
                            $(&#39;#content .Schedule&#39;).hide();
                            start_s();
                        }
                    }
                });
            });
            $(&#39;#clear&#39;).click(function () {
                $(&#39;#content ul li&#39;).remove();
            });
        });
</script> 
</head> 
<body> 
<div id="content"> 
 <h1>PHP远程图片抓取程序</h1> 
 <div class="h1"> 
    指定图片抓取:<input type="button" value=" 开始抓取 " id="Single" /> <font>目标网址如:http://www.phprm.com/123.jpg</font>  指定网址抓取:<input type="button" value=" 开始抓取 " id="more" /> <font>目标网址如:http://www.phprm.com</font>  <input type="button" value=" 清空状态信息 " id="clear" /> 
    </div> 
    <div class="Schedule"><font>正在抓取,请稍后...</font> <img  src="loading.gif" border="0" / alt="PHP+Ajax远程图片抓取器下载的例子 " ></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(&#39;Content-Type; text/json; charset=utf-8&#39;);
$Single = $_GET[&#39;Single&#39;];
$more = $_GET[&#39;more&#39;];
$TargetUrl = $_POST[&#39;TargetUrl&#39;];
$Save = $_POST[&#39;Save&#39;];
//判断是抓取单个图片还是多个图片
if ($Single == &#39;Single&#39;) {
    $ImageCatch = new ImageCatch($TargetUrl, $Save);
    $ImageCatch->S();
} else if ($more == &#39;more&#39;) {
    $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("&#39;", &#39;&#39;, $TargetUrl); //去掉单引号
        $this->Save = $Save;
    }
    //CSS样式表中图片抓取方法
    public function CSS() {
        $content = @file_get_contents($this->TargetUrl);
        //CSS图片过滤
        preg_match_all(&#39;/<link.+href="?(.*?.css)"?.+>/i&#39;, $content, $css);
        $css[1] = array_unique($css[1]); //移除重复的值
        $match2 = array();
        if (count($css[1]) > 0) {
            foreach ($css[1] as $val) {
                if (!preg_match(&#39;/^(https?://)/i&#39;, $val)) {
                    $val = $this->TargetUrl . &#39;/&#39; . $val;
                    $csscontent = @file_get_contents($val);
                } else {
                    $csscontent = @file_get_contents($val);
                }
                //匹配图片URL地址
                preg_match_all(&#39;/url((.*))/i&#39;,$csscontent,$cssimg); 
                $cssimg[1] = array_unique($cssimg[1]); //移除重复的值
                
            }
            foreach ($cssimg[1] as $val) {
                //去除 " ) 字符
                $val = preg_replace(array(
                    &#39;/"|)/&#39;
                ) , &#39;&#39;, $val);
                //去除../字符
                $val = str_replace(&#39;../&#39;, &#39;&#39;, $val);
                //检查是否是http://开头,如果不是则加上要抓取的网址
                if (!preg_match(&#39;/^(https?://)/i&#39;, $val)) {
                    array_push($match2, $this->TargetUrl . &#39;/&#39; . $val);
                } else {
                    array_push($match2, $val);
                }
            }
            return $match2;
        }
    }
    //计算并返回图片数量及地址
    public function M() {
        $content = @file_get_contents($this->TargetUrl);
        //网页图片过滤
        $str = &#39;/<img .+src="?(.+.(jpg|gif|bmp|bnp|png))"?.+ alt="PHP+Ajax远程图片抓取器下载的例子 " >/i&#39;;
        preg_match_all($str, $content, $res);
        if ($res[1]) {
            $res[1] = array_unique($res[1]); //移除重复的值
            $httpstr = &#39;/^(https?://)/i&#39;;
            $match = array();
            foreach ($res[1] as $val) {
                if (!preg_match($httpstr, $val)) {
                    array_push($match, $this->TargetUrl . &#39;/&#39; . $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(
                &#39;no&#39;
            );
            echo json_encode($res);
        }
        exit;
    }
    //抓取并保存图片
    public function S() {
        $this->Type = substr(strrchr($this->TargetUrl, &#39;.&#39;) , 1);
        $this->FileName = $this->Save . &#39;/&#39; . substr(strrchr($this->TargetUrl, &#39;/&#39;) , 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(&#39;{"status":"没有找到 &#39; . $this->TargetUrl . &#39; 图片"}&#39;);
        } else {
            $this->imageSize();
            exit(&#39;{"status":"ok","FileSave":"&#39; . $this->FileName . &#39;","FileSize":"&#39; . $this->Size . &#39;"}&#39;);
        }
    }
    //新建目录
    private function imageDir() {
        if (!@file_exists($this->Save)) {
            if (!@mkdir($this->Save, 0700)) {
                exit(&#39;{"status":"新建保存目录失败"}&#39;);
            }
        }
    }
    //文件类型判断
    private function imageType() {
        $typeArr = array(
            &#39;jpg&#39;,
            &#39;png&#39;,
            &#39;gif&#39;,
            &#39;zip&#39;,
            &#39;rar&#39;
        );
        if (!in_array($this->Type, $typeArr)) {
            exit(&#39;{"status":"要执行抓取的文件扩展名有错误,&#39; . $this->TargetUrl . &#39;"}&#39;);
        }
    }
    //文件大小检测
    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) . &#39; GB&#39;;
            } else if ($this->Size > 1024 * 1024) {
                $this->Size = round($this->Size / 1024 / 1024, 2) . &#39; MB&#39;;
            } else if ($this->Size > 1024) {
                $this->Size = $this->Size / 1024;
                $this->Size = ceil($this->Size) . &#39;KB&#39;;
            } else {
                $this->Size = $this->Size . &#39;bit&#39;;
            }
        } else {
            return &#39;未找到文件&#39;;
        }
    }
}

               
               

本文地址:

转载随意,但请附上文章地址:-)

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn