PHP采集程序中相对地址转换为绝对地址的函数

前一段时间在做PHP的采集时,发现有些网页采用相对地址来表示,这给采集带来了许多不便,需要一个可以将相对地址转换为绝对地址的函数,从网上找了一个,如下:

 

发现这个函数太简单了,不是代码简洁,而是功能简单,完全不够自己用,因为发现网页源文件有很多种格式的链接地址,比如:

0

A

B

C

D

C

D

E

……

于是不得已,只好自己写了一个函数,代码如下:

/* *函数名:url_relative_to_absolute($content, $url);——相对路径转化成绝对路径 *功能:本函数可以将网页源代码中的相对网址转换为绝对地址,支持网址多种格式,多种协议; * 支持页面源代码多种相对路径格式,并不会丢失或者篡改已有的绝对路径。 *参数:$content,页面源代码 * $url 当前页面的网址, *返回值:成功时将返回转换好后的页面源代码,失败时返回false供判断之用 *作者:[email protected] QQ:765365521,2009-6-3完成,2009-7-1修改#链接的bug */ function url_relative_to_absolute($content, $url) { $url = trim($url); preg_match('/(http|https|ftp)://///i', $url, $protocol); //获取协议:$protocol[0] $url_no_protocol = preg_replace("/(http|https|ftp|news)://///", "", $url); //清除协议头 $new_content = str_replace(array('"',"'"), array("",""), $content); //清除单双引号 //清除换行以及单双引号 //$new_content = str_replace(array("/r/n","/r","/n",'"',"'"), array("","","","",""), $content); $new_content = str_ireplace('href=#', 'href='.$url, $new_content); //预先清除链接为#格式 $new_content = str_ireplace('src=#', 'src='.$url, $new_content); //预先清除图片为#格式 $pattern = "/href=(?!(http:|https:|ftp:|news:|/.|//))/is"; $new_content = preg_replace($pattern, "href=./", $new_content); //将链接中的相对当前目录的路径统一 $pattern = "/src=(?!(http:|https:|ftp:|news:|/.|//))/is"; $new_content = preg_replace($pattern, "src=./", $new_content); //将链接中的相对当前目录的路径统一 //对网址先处理,便于识别,结果为:以/结束或者文件名结束 if($url_temp = strrchr($url_no_protocol, '/')) //从最后一个斜线开始检查 { //如果格式为http://www.dlmu.eud.cn/news或者http://www.dlmu.eud.cn/news/images/20090603等则加一个斜线 if(!strstr($url_temp, '.') && $url_temp != '/') $url_no_protocol .= '/'; }else{ $url_no_protocol .= '/'; } if(!isset($protocol[0]) || $protocol[0]=="" || empty($protocol[0])) return false; //将即可返回值,并停止执行以下代码,相当于die(); if(stristr($new_content,'href=/') || stristr($new_content,'src=/')) //根目录下 { //获取网址前缀 $url_array = explode('/', $url_no_protocol); $url_pre = $url_array[0]; //有没有斜线,都能获取到域名 //相对路径转化成绝对路径 $new_content = str_ireplace('href=/', 'href='.$protocol[0].$url_pre.'/', $new_content); $new_content = str_ireplace('src=/', 'src='.$protocol[0].$url_pre.'/', $new_content); } if(stristr($new_content,'href=./') || stristr($new_content,'src=./')) //当前目录中 { //获取网址前缀 $url_pre = substr($url_no_protocol, 0, strripos($url_no_protocol, '/')); //不包含斜线/ //相对路径转化成绝对路径 $new_content = str_ireplace('href=./', 'href='.$protocol[0].$url_pre.'/', $new_content); $new_content = str_ireplace('src=./', 'src='.$protocol[0].$url_pre.'/', $new_content); } //上N(1,2,3...)级目录时注意转换的顺序 if(stristr($new_content,'href=../../../') || stristr($new_content,'src=../../../')) //上三级目录中 { //获取网址前缀 if(substr_count($url_no_protocol,'/') >= 4) { $url_pre_temp = substr($url_no_protocol, 0, strripos($url_no_protocol, '/')); $url_pre_temp = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); $url_pre_temp = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); $url_pre = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); }else{ return false; //表明网址有错 } //相对路径转化成绝对路径 $new_content = str_ireplace('href=../../../', 'href='.$protocol[0].$url_pre.'/', $new_content); $new_content = str_ireplace('src=../../../', 'src='.$protocol[0].$url_pre.'/', $new_content); } if(stristr($new_content,'href=../../') || stristr($new_content,'src=../../')) //上两级目录中 { //获取网址前缀 if(substr_count($url_no_protocol,'/') >= 3) { $url_pre_temp = substr($url_no_protocol, 0, strripos($url_no_protocol, '/')); $url_pre_temp = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); $url_pre = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); }else{ return false; //表明网址有错 } //相对路径转化成绝对路径 $new_content = str_ireplace('href=../../', 'href='.$protocol[0].$url_pre.'/', $new_content); $new_content = str_ireplace('src=../../', 'src='.$protocol[0].$url_pre.'/', $new_content); } if(stristr($new_content,'href=../') || stristr($new_content,'src=../')) //上一级目录中 { //获取网址前缀 if(substr_count($url_no_protocol,'/') >= 2) { $url_pre_temp = substr($url_no_protocol, 0, strripos($url_no_protocol, '/')); $url_pre = substr($url_pre_temp, 0, strripos($url_pre_temp, '/')); }else{ return false; //表明网址有错 } //相对路径转化成绝对路径 $new_content = str_ireplace('href=../', 'href='.$protocol[0].$url_pre.'/', $new_content); $new_content = str_ireplace('src=../', 'src='.$protocol[0].$url_pre.'/', $new_content); } return $new_content; }

 

经测试,能将$url页面中的HTML的相对地址转换为绝对地址。$url格式可以为如下形式:

http://www.cnisme.cn
http://www.cnisme.cn/
http://www.cnisme.cn/news
http://www.cnisme.cn/news/
http://www.cnisme.cn/news/index.php
http://www.cnisme.cn/news/images/20090603
http://www.cnisme.cn/news/images/20090603/
http://www.cnisme.cn/news/images/20090603/hi.gif
基本实现预期效果。

你可能感兴趣的:(PHP采集程序中相对地址转换为绝对地址的函数)