[PHP] Pobieranie opisu, tytułu, słów kluczowych z dowolnej strony

Ostatnio musiałem napisać klasę pobierającą meta dane (description, keywords) oraz tytuł strony.
O ile z tytułem strony nie było problemu:

preg_match("/<title>(.*)<\/title>/i", $content, $matches);

…to z meta danymi już tak. Co prawda PHP posiada funkcję get_meta_tags – jednak ona wykonuje dodatkowe zapytanie do serwera. Aby tego uniknąć – zakładając że mamy już treść strony (pobieraliśmy ją do wyciągnięcia tytułu) – należy przeparsować jeszcze raz:

preg_match_all('/<[\s]*meta[\s]*name="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', $content, $matches);

Dzięki temu odpytanie o dowolną stronę trwa (z grubsza) dwa razy szybciej :)
Całość może wyglądać tak (niezbędna obsługa CURL)

<?php

include_once '../curl/curl.class.php';

class meta
{
    var $url;
    var $data;
    var $content;
    var $keywordMinLen = 3;

    function meta( $url = null )
    {
        $this->url = $url;
        $this->data->title = null;
        $this->data->meta  = null;
    }

    function getUrl()
    {
        $result = curl::getFile( $this->url );
        $this->content = $result->data;
    }

    function getInfo()
    {
        $this->getUrl();
        $this->data->title = $this->getTitle();
        $this->data->meta  = $this->getMeta();

        return $this->data;
    }

    function getMeta()
    {
        $meta = array();
        preg_match_all('/<[\s]*meta[\s]*name="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', $this->content, $matches);

        if (isset($matches) && is_array($matches))
        {
            if (count($matches[1]) == count($matches[2]))
            {
                for ($i=0, $cnt = count($matches[1]); $i < $cnt; ++$i)
                {
                    $meta[ strtolower($matches[1][$i]) ] = $matches[2][$i];
                }
            }
        }

        return $meta;
    }

    function getTitle()
    {
        if( isset($this->data->title) && !empty($this->data->title) )
        {
            $matches[1] = $this->data->title;
        }
        else
        {
            preg_match("/<title>(.*)<\/title>/i", $this->content, $matches);
        }
        return isset($matches[1]) ? $matches[1] : null;
    }
}

?>

Wykorzystanie

    $site = new meta( 'wykop.pl' );
    $site->getInfo();
    print_r( $site->data );

Rezultat

stdClass Object
(
    [title] => Wykop.pl - newsy, aktualności, gry, wiadomości, muzyka, polityka, filmiki
    [meta] => Array
        (
            [robots] => follow, index
            [description] => Wykop jest miejscem, gdzie gromadzimy najciekawsze informacje z Sieci: newsy, artykuły, linki. O treści serwisu decydują tylko i wyłącznie nasi użytkownicy, dodając newsy, komentując i głosując na nie.
            [keywords] => Newsy, Aktualności, Gry komputerowe, super filmiki, wiadomości, Polityka, Filmiki z humorem, śmieszne filmy, muzyka na codzień
            [verify-v1] =>
            [google-site-verification] => V4MUQ9RWTEmDapezxuye8fqvShDIixA1oYzAytVf-ys
        )

)
Tags: , ,