在采集的时候,经常会遇到一些src=./abc.html,abc.html,../abc.html这样的形式的
print normalUrl(“./abc.html”,”http://www.trackself.com/abc/efg/a.html”);//输出http://www.trackself.com/abc/efg/abc.html
这个函数我测试了将近一小时了,大部分情况下还是可用的,但由于URL的多变性,应该也有不适用的可能(目前我没遇到)
function normalUrl($url,$comFrom){
//该函数将一个URL还原为完整形式
//一般来说要调用该函数,说明此URL并非以http开始,或者以./等为始
//$comFrom应该是该URL是从什么得来的
static $sc;//用于存放parse_url($comFrom),免得当大量URL时重复运算
$url=trim($url);
if(empty($url)){
return $url;
}
$purl=parse_url($url);
if(empty($purl['host'])){//此URL是不完整的
if(empty($sc[$comFrom])){
$sc[$comFrom]=parse_url($comFrom);
}
$purl['scheme']=$sc[$comFrom]['scheme'];
$purl['host']=$sc[$comFrom]['host'];
$fir=substr($url,0,1);
if($fir==”.”){
if(substr($url,0,2)==”./”){ //只处理只有一个./的情况
$str=substr($url,2);
$self=selfFolder($comFrom);
return $self.”/”.$str;
}elseif(substr($url,0,3)==”../”){
$str=substr($url,3);
$back=backFolder($comFrom);
return $back.”/”.$str;
}
}elseif($fir==”/”){
return $purl['scheme'].”://”.$purl['host'].$url;
}else{
$self=selfFolder($comFrom);
return $self.”/”.$url;
}
}else{
return $url;
}
}
function backFolder($url){
//后退一层目录:如:当http://wwww.trackself.com/abc/bcd/c.html,应该输出当http://wwww.trackself.com/abc/
static $result;
if(isset($result[$url])){
return $result[$url];
}
$self=selfFolder($url);
/*
$purl=parse_url($url);
if(empty($purl['path']) || $purl['path']==”/”){//这种情况几乎不出现,除非网站出错
return $url;
}
*/
$d=explode(“/”,$self);
array_pop($d);
$result[$url]=implode(“/”,$d);
return $result[$url];
}
function selfFolder($url){
//$url是一个完整的URL
//得到一个URL的目录结构:例如:当http://wwww.trackself.com/abc/bcd/c.html,应该输出当http://wwww.trackself.com/abc/bcd/
static $result;
if(isset($result[$url])){
return $result[$url];
}
$purl=parse_url($url);
$url=$purl['scheme'].”://”.$purl['host'].$purl['path'];
//$real=$purl['scheme'].”://”.$purl['host'].$purl['path'];//去掉了?以后的全部内容
if(empty($purl['path']) || strlen($purl['path'])<5){
//正常的html,至少是域名后有一个“/”然后有.html.htm.asp.php.pl,所以最少的长度应该是5.即/a.pl
//如果小于5,则基本可认为它是一个文件夹
$result[$url]=$url;
return $url;
}
$x=explode(“.”,$purl['path']);
if(count($x)<2){//没后辍,只能是文件夹
$result[$url]=$url;
return $url;
}
$y=array_pop($x);//取得可能是后辍的串
if(strlen($y)>5){//太长,一定不是正常文件
$result[$url]=$url;
return $url;
}
$ez=explode(“/”,$purl['path']);
$z=array_pop($ez);//取得最后一个可能是文件名的串
//对比$y,$z
if(strlen($y)>=strlen($z)){//文件名应该大于后辍
$result[$url]=$url;
return $url;
}
switch($y){
case “php”:
case “htm”:
case “jsp”:
case “html”:
case “asp”:
case “aspx”:
case “py”:
case “shtml”:
case “xml”:
case “rss”:
case “xhtml”:
$result[$url]=$purl['scheme'].”://”.$purl['host'].implode(“/”,$ez);
return $result[$url];
break;
}
$result[$url]=$url;
return $url;
}