Как получить окончательный перенаправленный канонический URL-адрес веб-сайта с помощью PHP?

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

Я видел этот пример кода, но он не обрабатывает такие вещи, как метатеги rel="canonical" или порты ssl по умолчанию: http://w-shadow.com/blog/2008/07/05

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, которые можно использовать, но предпочел бы что-то, что работает на моем собственном сервере.


person Matt    schedule 01.12.2011    source источник
comment
Проверьте это, stackoverflow.com/questions/4454605 /   -  person Srisa    schedule 01.12.2011
comment
Я не знаю, понимаю ли я ваш вопрос, но я думаю, вам следует проверить это php.net/manual/es/reserved.variables.server.php   -  person NotGaeL    schedule 01.12.2011
comment
Спасибо, Шриса, это общая идея, но curl не следует перенаправлениям метатегов, как отмечается в принятом ответе... Решение потребует некоторого синтаксического анализа HTML для окончательной перенаправленной ссылки, а затем потенциально больше перенаправлений до тех пор, пока цикл находится или мы достигаем конца цепочки перенаправления и rel=canonical... Просто надеялся, что кто-то уже написал это, так что мне не нужно. :)   -  person Matt    schedule 01.12.2011
comment
парсер PHP HTML   -  person Mario Lurig    schedule 01.12.2011
comment
Спасибо, ребята, я знаю, как анализировать HTML или использовать preg_match(), чтобы просто быстро извлечь этот тег. Может быть, искать библиотеку слишком сложно, но я действительно надеялся, что есть кто-то, кто нашел время, чтобы сделать это правильно... Например, даже принимая во внимание хэш-банг и экранированный код фрагмента Google (и, возможно, другие вещи, о которых я даже не думал, связанные с перенаправлением URL).   -  person Matt    schedule 01.12.2011


Ответы (3)


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

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

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

  • Выполняет переадресацию 301 и 302 в заголовках HTTP
  • Отслеживает ‹метатеги› URL Open Graph, найденные на веб-странице ‹head›
  • Следует каноническим URL-тегам ‹link›, найденным на веб-странице ‹head›
  • Быстро прерывает загрузку, если тип содержимого не является HTML-страницей

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

person Matt    schedule 04.12.2011

Используя 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();
}
person Damien    schedule 24.07.2014

Я написал вам небольшую функцию, чтобы сделать это. Это просто, но может стать отправной точкой для вас. Примечание. 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' );

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

person Homer6    schedule 03.12.2011
comment
Спасибо, Гомер, я ценю усилия. Поскольку я не получаю никаких предложений по библиотеке, я решил начать писать свою собственную и опубликую ее здесь (и на github), когда это будет сделано в ближайшие пару дней... На самом деле я ищу что-то более продвинутое, чем следующие просто перенаправления заголовка местоположения. Я хочу, чтобы он анализировал ‹head› страницы, чтобы получить канонические URL-адреса и URL-адреса с открытым графиком, следовать им и т. Д. Пока библиотека содержит около 500 строк кода, но она близка к тому, чтобы работать так, как я хочу. :) - person Matt; 03.12.2011
comment
Звучит хорошо, Мэтт... с нетерпением жду того, что у тебя есть. Ваше здоровье. - person Homer6; 03.12.2011