欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

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

程序员文章站 2022-05-01 17:24:14
...
发送请求:将输入的目标网址及保存路径名称采用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代码如下:

 
 
 
PHP远程图片抓取

PHP远程图片抓取程序

指定图片抓取: 目标网址如:http://www.phprm.com/123.jpg  指定网址抓取: 目标网址如:http://www.phprm.com  
正在抓取,请稍后... PHP+Ajax远程图片抓取器下载的例子
目标网址: 保存地址:

    images.info.php,代码如下:

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


    本文地址:

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