13

在链接缩短器和 Ajax 时代,可能有许多链接最终指向相同的内容。我想知道最好的方法是用 PHP 获得最终的、最好的网站链接,希望有一个库。我在 Google 或 GitHub 上找不到任何东西。

我看过这个示例代码,但它不处理 rel="canonical" 元标记或默认 ssl 端口之类的东西:http ://w-shadow.com/blog/2008/07/05/how-to-获取重定向 url-in-php/

Facebook 似乎处理得很好,您可以看到他们如何遵循 301 和 rel="canonical" 等。要查看 Facebook 处理方式的示例,请使用他们的 Open Graph 工具:

https://developers.facebook.com/tools/debug

并输入这些链接:

http://dlvr.it/xxb0W
https://twitter.com/#!/twitter/statuses/136946408275193856

是否有一个 PHP 库已经预先构建了这个库,它将检查这些标头、解析 301 重定向、解析 rel="canonical"、检测重定向循环并正确地获取要使用的最佳结果 URL?

作为替代方案,我对可以使用的 API 持开放态度,但更喜欢在我自己的服务器上运行的东西。

4

3 回答 3

13

由于我无法找到任何真正符合我要求的库,并且我希望做的不仅仅是遵循 HTTP 重定向,因此我继续创建了一个实现目标的库,并在 MIT 下发布了它执照。你可以在这里得到它:

https://github.com/mattwright/URLResolver.php

URLResolver.php 是一个 PHP 类,它尝试将 URL 解析为最终的规范链接:

  • 遵循 HTTP 标头中的 301 和 302 重定向
  • 遵循网页 <head> 中的 Open Graph URL <meta> 标签
  • 遵循网页 <head> 中的规范 URL <link> 标签
  • 如果内容类型不是 HTML 页面,则快速中止下载

我当然不是 HTTP 重定向规则方面的专家,所以如果有人对如何改进这个库有任何建议,我将不胜感激。我已经在数千个 URL 上进行了测试,它似乎做得很好。我听从了 Mario 的建议,并在需要的地方使用了 PHP Simple HTML Parser 库。

于 2011-12-04T07:48:36.527 回答
2

使用 Guzzle(一个众所周知且强大的 HTTP 客户端),您可以这样做:

<?php
use Guzzle\Http\Client as GuzzleClient;
use Guzzle\Plugin\History\HistoryPlugin;

public function resolveUrl($url)
{
    $client   = new GuzzleClient($url);
    $history  = new HistoryPlugin();
    $client->addSubscriber($history);

    $response = $client->head($url)->send();

    if (!$response->isSuccessful()) {
        throw new \Exception(sprintf("Url %s is not a valid URL or website is down.", $url));
    }

    return $response->getEffectiveUrl();
}
于 2014-07-24T13:10:47.560 回答
0

我给你写了一个小函数来做到这一点。这很简单,但它可能是您的起点。注意:http://dlvr.it/xxb0W url 为它的 Location 响应头返回一个无效的 URL。

您需要 Altumo PHP 库才能使其工作。这是我编写的一个库,但它是 MIT 许可证,这个函数也是如此。

见:https ://github.com/homer6/altumo

此外,您必须将函数包装在 try/catch 中。

/**
* Gets the final URL of a URL that will be redirected.
* 
* @param string $url_string
* @throws \Exception                    //on error
* @return string
*/
function get_final_url( $url_string ){

    while( 1 ){

        //validate URL
            $url = new \Altumo\String\Url( $url_string );

        //get the Location response header of the URL
            $client = new \Altumo\Http\OutgoingHttpRequest( $url_string );
            $response = $client->sendAndGetResponseMessage();
            $location = $response->getHeader( 'Location' );

        //return the URL if no Location header was found, else continue
            if( is_null($location) ){
                return $url_string;
            }else{
                $url_string = $location;
            }

    }

}

echo get_final_url( 'your url here' );

如果您需要进一步的修改或帮助进行,请告诉我。

于 2011-12-03T04:49:50.843 回答