PHP+Ajax远程图片抓取器下载的例子
发送请求:将输入的目标网址及保存路径名称采用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) {
$('#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.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" /></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 '未找到文件';
}
}
}
本文地址:http://www.phprm.com/develop/fs5961.html
转载随意,但请附上文章地址:-)