首页 > PHP > PHP爬虫将相对链接转化为绝对链接

PHP爬虫将相对链接转化为绝对链接

在写PHP爬虫的时候,总会遇到各种各样奇怪的链接,有写绝对链接的,有写相对链接的,也有写不带域名的绝对链接的,遇到这样的请求需要将这些链接转换为绝对链接,这样可以统一处理。

1.绝对链接:例如<a target="_blank" href="http://blog.zhengshuiguang.com">同级目录下的文件</a>

这种情况是最容易的,不需要处理,直接获取即可。


2.相对链接:在http://blog.zhengshuiguang.com首页出现以下2个a标签。

<a id="same" target="_blank" href="about.html">同级目录下的文件</a>
<a id="other" target="_blank" href="php/relative-href.html">子目录下的文件</a>

对于第一个a标签,其绝对路径为http://blog.zhengshuiguang.com/about.html,其获取方式为

'http://blog.zhengshuiguang.com'.'/'.'about.html'

对于第二个a标签,其绝对路径为http://blog.zhengshuiguang.com/php/relative-href.html,其获取方式为

'http://blog.zhengshuiguang.com'.'/'.'php/relative-href.html'


3.不带域名的绝对链接:本站大部分图片都是采用不带域名的绝对链接

<img src="/usr/uploads/2015/08/29/1440861877357364.png" title="1440861877357364.png" alt="blob.png">

其绝对路径为http://blog.zhengshuiguang.com/usr/uploads/2015/08/29/1440861877357364.png,其获取方式为

'http://blog.zhengshuiguang.com'.'/usr/uploads/2015/08/29/1440861877357364.png'

可是,如果在http://blog.zhengshuiguang.com/software/win10-android.html这个页面来获取该png图片的绝对路径不是非常容易,因为你需要

对"http://blog.zhengshuiguang.com/software/win10-android.html"进行处理来获取所在域名"http://blog.zhengshuiguang.com",然后拼凑"/usr/uploads/2015/08/29/1440861877357364.png"部分。


这里将这3种情况进行条件判断,综合出以下方法:

<?php
/**
 * 将相对链接转换为绝对链接
 * @param string $link
 * @param string $url
 * @return string
 */
function fix_relative_path($link, $url='') {
    if($url) {
        //去掉$url可能的参数
        $url = subByString($url, '', '?');
        $url = subByString($url, '', '#');
        if(strpos($link, '/') === 0)
        {
            $info = parse_url($url);
            if(isset($link[1]) && $link[1] === '/')
            {
                $link = $info['scheme'].':'.$link;
            }else{
                $info = parse_url($url);
                if(isset($info['port']))
                {
                    $link = subByString($url, '', $info['host']).$info['host'].':'.$info['port'].$link;
                }else{
                    $link = subByString($url, '', $info['host']).$info['host'].$link;
                }
            }
        }else if(strpos($link, 'http') === 0)
        {
             
        }else{
            $parent = dirname($url);
            if(substr($parent, -1) === ':' || $url[strlen($url)-1] === '/')
            {
                $link = trim($url, '/').'/'.$link;
            }else{
                $link = $parent.'/'.$link;
            }
        }
    }
    return str_replace('/./', '/', $link);
}

/**
 * 用于字符串截取,用于截取2个字符串之间的内容,不含边界
 * @param string $haystack
 * @param string $left
 * @param string $right
 * @return string
 */
function subByString($haystack, $left = '', $right = '')
{
    $left_pos = false;
    $right_pos = false;
    if($left == '' || ($left_pos = strpos($haystack, $left)) === false)
    {
        $start_pos = 0;
    }else{
        $start_pos = $left_pos;
    }
    $right_data = substr($haystack, $start_pos + ($left_pos === false ? 0 : strlen($left)));
    if($right == '' || ($right_pos = strpos($right_data, $right)) === false)
    {
        return substr($haystack, $left_pos === false ? 0 : $left_pos+strlen($left));
    }else{
        $end_pos = $start_pos + $right_pos;
        return substr($haystack, $left_pos === false ? 0 : $left_pos+strlen($left), $end_pos-$start_pos);
    }
}

$link为a标签的href属性,$url为a标签所在页面的完整路径,考虑到$url带各种各样的参数,使用subByString去除可以得到比较纯净的网址。然后分3种情况进行判断以获取绝对链接地址。


修复,考虑到越来越多的网站开始使用https,往往在写资源的路径的时候不写http://或https://,而是写//

例如://blog.zhengshuiguang.com/,增加if(strpos($link, '//') === 0)判断即可。

还有各种其他协议,但是网页中出现较少的,如ftp等自行写判断。





本文地址:http://blog.zhengshuiguang.com/php/relative-href.html

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

标签:爬虫 相对链接 绝对链接 获取域名 去除参数

相关文章

评论已关闭