Как получить окончательный, перенаправленный, канонический URL-адрес веб-сайта с использованием PHP? - PullRequest
13 голосов
/ 01 декабря 2011

В дни сокращения ссылок и Ajax может быть много ссылок, которые в конечном итоге указывают на один и тот же контент. Мне было интересно, как лучше всего получить окончательную, лучшую ссылку для веб-сайта на PHP, надеюсь, с библиотекой. Мне не удалось найти что-либо в Google или GitHub.

Я видел этот пример кода, но он не обрабатывает такие вещи, как мета-теги rel = "canonical" или ssl-порты по умолчанию: http://w -shadow.com / blog / 2008/07/05 / как к получить переадресовывать-url-в-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, которые можно использовать, но предпочел бы что-то, что работает на моем собственном сервере.

Ответы [ 3 ]

12 голосов
/ 04 декабря 2011

Поскольку я не смог найти ни одной библиотеки, которая действительно выполняла бы то, что я искал, и я надеялся сделать больше, чем просто следовать HTTP-перенаправлениям, я пошел дальше и создал библиотеку, которая выполняет поставленные цели, и выпустил ее.под лицензией MIT.Вы можете получить его здесь:

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

URLResolver.php - это класс PHP, который пытается преобразовать URL-адреса в окончательную каноническую ссылку:

  • FollowsПеренаправления 301 и 302, найденные в заголовках HTTP
  • Следуют по URL-адресу Open Graph теги, найденные на веб-странице
  • Следуют каноническим URL теги, найденныевеб-страница
  • Прерывает загрузку быстро, если тип контента не является HTML-страницей

Я, конечно, не эксперт по правилам перенаправления HTTP, поэтому если кто-нибудьесть предложения о том, как улучшить эту библиотеку, было бы очень признательно.Я проверил на тысячах URL-адресов, и, кажется, это очень хорошо.Я последовал совету Марио и использовал библиотеку PHP Simple HTML Parser, где это было необходимо.

2 голосов
/ 24 июля 2014

Используя 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();
}
0 голосов
/ 03 декабря 2011

Я написал вам небольшую функцию, чтобы сделать это. Это просто, но это может быть отправной точкой для вас. Примечание. URL-адрес http://dlvr.it/xxb0W возвращает недопустимый URL-адрес для заголовка ответа Location.

Для работы вам потребуется PHP-библиотека Altumo. Это библиотека, которую я написал, но это лицензия 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' );

Пожалуйста, дайте мне знать, если вам нужны дальнейшие модификации или вы хотите помочь.

...