【问题标题】:Getting Absolute Path of External Web Page Images获取外部网页图片的绝对路径
【发布时间】:2011-12-20 08:48:37
【问题描述】:

我正在处理书签,我正在使用 HTML DOM 解析器获取任何外部页面的所有照片(正如 SO answer 之前所建议的那样)。我正在正确获取照片并将其显示在我的书签弹出窗口中。但我对照片的相对路径有疑问。

例如外部页面上的照片来源说http://www.example.com/dir/index.php

  1. 照片来源 1:img source='hostname/photos/photo.jpg' - 按原样获取照片

  2. 照片来源 2:img source='/photos/photo.jpg' - 没有得到,因为它不是绝对的。

我通过当前 url 工作,我的意思是使用 dirname 或 pathinfo 通过当前 url 获取目录。但会导致 host/dir/ (将 host 作为父目录)和 host/dir/index.php (host/dir 作为父目录是正确的)之间的问题

请帮忙 我怎样才能得到这些相关的照片??

【问题讨论】:

  • 那个“链接”呢?我的意思是“/photo/xdfa.jpg”只会从域地址中考虑它。你也可以试试'./path/pics.jpg';它对我有用
  • 那么问题出在哪里?如何检测字符串是否以http:///开头?

标签: php html dom


【解决方案1】:

已修复(增加了对仅查询字符串图像路径的支持)

function make_absolute_path ($baseUrl, $relativePath) {

    // Parse URLs, return FALSE on failure
    if ((!$baseParts = parse_url($baseUrl)) || (!$pathParts = parse_url($relativePath))) {
        return FALSE;
    }

    // Work-around for pre- 5.4.7 bug in parse_url() for relative protocols
    if (empty($baseParts['host']) && !empty($baseParts['path']) && substr($baseParts['path'], 0, 2) === '//') {
        $parts = explode('/', ltrim($baseParts['path'], '/'));
        $baseParts['host'] = array_shift($parts);
        $baseParts['path'] = '/'.implode('/', $parts);
    }
    if (empty($pathParts['host']) && !empty($pathParts['path']) && substr($pathParts['path'], 0, 2) === '//') {
        $parts = explode('/', ltrim($pathParts['path'], '/'));
        $pathParts['host'] = array_shift($parts);
        $pathParts['path'] = '/'.implode('/', $parts);
    }

    // Relative path has a host component, just return it
    if (!empty($pathParts['host'])) {
        return $relativePath;
    }

    // Normalise base URL (fill in missing info)
    // If base URL doesn't have a host component return error
    if (empty($baseParts['host'])) {
        return FALSE;
    }
    if (empty($baseParts['path'])) {
        $baseParts['path'] = '/';
    }
    if (empty($baseParts['scheme'])) {
        $baseParts['scheme'] = 'http';
    }

    // Start constructing return value
    $result = $baseParts['scheme'].'://';

    // Add username/password if any
    if (!empty($baseParts['user'])) {
        $result .= $baseParts['user'];
        if (!empty($baseParts['pass'])) {
            $result .= ":{$baseParts['pass']}";
        }
        $result .= '@';
    }

    // Add host/port
    $result .= !empty($baseParts['port']) ? "{$baseParts['host']}:{$baseParts['port']}" : $baseParts['host'];

    // Inspect relative path path
    if ($relativePath[0] === '/') {

        // Leading / means from root
        $result .= $relativePath;

    } else if ($relativePath[0] === '?') {

        // Leading ? means query the existing URL
        $result .= $baseParts['path'].$relativePath;

    } else {

        // Get the current working directory
        $resultPath = rtrim(substr($baseParts['path'], -1) === '/' ? trim($baseParts['path']) : str_replace('\\', '/', dirname(trim($baseParts['path']))), '/');

        // Split the image path into components and loop them
        foreach (explode('/', $relativePath) as $pathComponent) {
            switch ($pathComponent) {
                case '': case '.':
                    // a single dot means "this directory" and can be skipped
                    // an empty space is a mistake on somebodies part, and can also be skipped
                    break;
                case '..':
                     // a double dot means "up a directory"
                    $resultPath = rtrim(str_replace('\\', '/', dirname($resultPath)), '/');
                    break;
                default:
                    // anything else can be added to the path
                    $resultPath .= "/$pathComponent";
                    break;
            }
        }

        // Add path to result
        $result .= $resultPath;

    }

    return $result;

}

测试:

echo make_absolute_path('http://www.example.com/dir/index.php','/photos/photo.jpg')."\n";
// Outputs: http://www.example.com/photos/photo.jpg
echo make_absolute_path('http://www.example.com/dir/index.php','photos/photo.jpg')."\n";
// Outputs: http://www.example.com/dir/photos/photo.jpg
echo make_absolute_path('http://www.example.com/dir/index.php','./photos/photo.jpg')."\n";
// Outputs: http://www.example.com/dir/photos/photo.jpg
echo make_absolute_path('http://www.example.com/dir/index.php','../photos/photo.jpg')."\n";
// Outputs: http://www.example.com/photos/photo.jpg
echo make_absolute_path('http://www.example.com/dir/index.php','http://www.yyy.com/photos/photo.jpg')."\n";
// Outputs: http://www.yyy.com/photos/photo.jpg
echo make_absolute_path('http://www.example.com/dir/index.php','?query=something')."\n";
// Outputs: http://www.example.com/dir/index.php?query=something

我认为这应该可以处理您可能正确遇到的所有事情,并且应该大致等同于浏览器使用的逻辑。还应该纠正您在 Windows 上使用 dirname() 时可能会出现杂散正斜杠的任何奇怪问题。

第一个参数是您找到<img>(或<a> 或其他)的页面的完整 URL,第二个参数是src/href 等的内容属性。

如果有人发现某些东西不起作用(因为我知道你们都会尝试破坏它 :-D),请告诉我,我会尝试修复它。

【讨论】:

  • @Rohit 我刚刚添加了几个小修复 :-)
【解决方案2】:

'/' 应该是基本路径。检查 dom 解析器返回的第一个字符,如果是 '/' 则只需在其前面加上域名即可。

【讨论】:

  • 好的,谢谢..你能告诉我当主网站是子目录时的情况......www.yahoo.com/news/....它将返回www .yahoo.com 作为域名,因此图像路径检测将失败。
  • 通常,您应该始终使用完整的基本路径 + 图像路径(如您提供的 #1 示例)。只有在 img src 以“/”开头的情况下,您才应该使用完整路径减去第一个正斜杠之后的所有内容。所以 www.yahoo.com/finance/AAPL => www.yahoo.com 然后添加 img src: '/photos/photo.jpg'。你的 DOM 解析器是用什么语言编写的?
猜你喜欢
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多