Heim  >  Artikel  >  php教程  >  PHP+Ajax远程图片抓取器下载的例子

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

WBOY
WBOYOriginal
2016-06-02 09:13:451262Durchsuche

发送请求:将输入的目标网址及保存路径名称采用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;;
        }
    }
}

               
               

本文地址:

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

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn