web-dev-qa-db-fra.com

Obtention de titres et de balises meta sur un site Web externe

Je veux essayer de comprendre comment obtenir le

<title>A common title</title>
<meta name="keywords" content="Keywords blabla" />
<meta name="description" content="This is the description" />

Même si, dans quelque ordre que ce soit, j'ai entendu parler de PHP Simple HTML DOM Parser, mais je ne veux pas vraiment l'utiliser. Est-il possible pour une solution d'utiliser le <PHP - Simple HTML DOM Parser. 

preg_match ne pourra-t-il pas le faire si le code HTML est invalide?

Est-ce que cURL peut faire quelque chose comme ça avec preg_match?

Facebook fait quelque chose comme ça mais il est bien utilisé en utilisant:

<meta property="og:description" content="Description blabla" />

Je veux quelque chose comme ça pour qu'il soit possible quand quelqu'un poste un lien, il devrait récupérer le titre et les balises méta. S'il n'y a pas de balises META, il est ignoré ou l'utilisateur peut le définir lui-même (mais je le ferai plus tard moi-même).

51
MacMac

Ceci est la façon dont il devrait être:

function file_get_contents_curl($url)
{
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

    $data = curl_exec($ch);
    curl_close($ch);

    return $data;
}

$html = file_get_contents_curl("http://example.com/");

//parsing begins here:
$doc = new DOMDocument();
@$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName('title');

//get and display what you need:
$title = $nodes->item(0)->nodeValue;

$metas = $doc->getElementsByTagName('meta');

for ($i = 0; $i < $metas->length; $i++)
{
    $meta = $metas->item($i);
    if($meta->getAttribute('name') == 'description')
        $description = $meta->getAttribute('content');
    if($meta->getAttribute('name') == 'keywords')
        $keywords = $meta->getAttribute('content');
}

echo "Title: $title". '<br/><br/>';
echo "Description: $description". '<br/><br/>';
echo "Keywords: $keywords";
151
shamittomar
<?php
// Assuming the above tags are at www.example.com
$tags = get_meta_tags('http://www.example.com/');

// Notice how the keys are all lowercase now, and
// how . was replaced by _ in the key.
echo $tags['author'];       // name
echo $tags['keywords'];     // php documentation
echo $tags['description'];  // a php manual
echo $tags['geo_position']; // 49.33;-86.59
?>
34
Bob Jeey

get_meta_tags vous aidera avec tout sauf le titre. Pour obtenir le titre, utilisez simplement une regex.

$url = 'http://some.url.com';
preg_match("/<title>(.+)<\/title>/siU", file_get_contents($url), $matches);
$title = $matches[1];

J'espère que cela pourra aider.

8
Lloyd Moore

La fonction native de Php: Get_meta_tags ()

http://php.net/manual/en/function.get-meta-tags.php

6
Nitroware

get_meta_tags ne fonctionnait pas avec le titre.

Seules les balises meta avec des attributs de nom comme 

<meta name="description" content="the description">

sera analysé.

4
Harald

Malheureusement, la fonction php intégrée get_meta_tags () nécessite le paramètre name, et certains sites, tels que Twitter, le laissent passer en faveur de l'attribut property. Cette fonction, utilisant un mélange de regex et de document dom, renverra un tableau de métatags à clé à partir d’une page Web. Il vérifie le paramètre name, puis le paramètre property. Cela a été testé sur instragram, pinterest et Twitter.

/**
 * Extract metatags from a webpage
 */
function extract_tags_from_url($url) {
  $tags = array();

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

  $contents = curl_exec($ch);
  curl_close($ch);

  if (empty($contents)) {
    return $tags;
  }

  if (preg_match_all('/<meta([^>]+)content="([^>]+)>/', $contents, $matches)) {
    $doc = new DOMDocument();
    $doc->loadHTML('<?xml encoding="utf-8" ?>' . implode($matches[0]));
    $tags = array();
    foreach($doc->getElementsByTagName('meta') as $metaTag) {
      if($metaTag->getAttribute('name') != "") {
        $tags[$metaTag->getAttribute('name')] = $metaTag->getAttribute('content');
      }
      elseif ($metaTag->getAttribute('property') != "") {
        $tags[$metaTag->getAttribute('property')] = $metaTag->getAttribute('content');
      }
    }
  }

  return $tags;
}
4
oknate

Votre meilleur pari est de mordre la balle en utilisant l’analyseur DOM - c’est la «bonne façon» de le faire. À long terme, cela vous fera gagner plus de temps que nécessaire pour apprendre à le faire. L'analyse de HTML avec Regex est reconnue pour son manque de fiabilité et son intolérance aux cas particuliers. 

4
Joshua

http://php.net/manual/en/function.get-meta-tags.php

<?php
// Assuming the above tags are at www.example.com
$tags = get_meta_tags('http://www.example.com/');

// Notice how the keys are all lowercase now, and
// how . was replaced by _ in the key.
echo $tags['author'];       // name
echo $tags['keywords'];     // php documentation
echo $tags['description'];  // a php manual
echo $tags['geo_position']; // 49.33;-86.59
?>   
3
afro360

Nous utilisons Apache Tika via php (utilitaire de ligne de commande) avec -j pour json:

http://tika.Apache.org/

<?php
    Shell_exec( 'Java -jar tika-app-1.4.jar -j http://www.guardian.co.uk/politics/2013/jul/21/tory-strategist-lynton-crosby-lobbying' );
?>

Voici un exemple output d'un article de gardien aléatoire:

{
   "Content-Encoding":"UTF-8",
   "Content-Length":205599,
   "Content-Type":"text/html; charset\u003dUTF-8",
   "DC.date.issued":"2013-07-21",
   "X-UA-Compatible":"IE\u003dEdge,chrome\u003d1",
   "application-name":"The Guardian",
   "article:author":"http://www.guardian.co.uk/profile/nicholaswatt",
   "article:modified_time":"2013-07-21T22:42:21+01:00",
   "article:published_time":"2013-07-21T22:00:03+01:00",
   "article:section":"Politics",
   "article:tag":[
      "Lynton Crosby",
      "Health policy",
      "NHS",
      "Health",
      "Healthcare industry",
      "Society",
      "Public services policy",
      "Lobbying",
      "Conservatives",
      "David Cameron",
      "Politics",
      "UK news",
      "Business"
   ],
   "content-id":"/politics/2013/jul/21/tory-strategist-lynton-crosby-lobbying",
   "dc:title":"Tory strategist Lynton Crosby in new lobbying row | Politics | The Guardian",
   "description":"Exclusive: Firm he founded, Crosby Textor, advised private healthcare providers how to exploit NHS \u0027failings\u0027",
   "fb:app_id":180444840287,
   "keywords":"Lynton Crosby,Health policy,NHS,Health,Healthcare industry,Society,Public services policy,Lobbying,Conservatives,David Cameron,Politics,UK news,Business,Politics",
   "msapplication-TileColor":"#004983",
   "msapplication-TileImage":"http://static.guim.co.uk/static/a314d63c616d4a06f5ec28ab4fa878a11a692a2a/common/images/favicons/windows_tile_144_b.png",
   "news_keywords":"Lynton Crosby,Health policy,NHS,Health,Healthcare industry,Society,Public services policy,Lobbying,Conservatives,David Cameron,Politics,UK news,Business,Politics",
   "og:description":"Exclusive: Firm he founded, Crosby Textor, advised private healthcare providers how to exploit NHS \u0027failings\u0027",
   "og:image":"https://static-secure.guim.co.uk/sys-images/Guardian/Pix/pixies/2013/7/21/1374433351329/Lynton-Crosby-008.jpg",
   "og:site_name":"the Guardian",
   "og:title":"Tory strategist Lynton Crosby in new lobbying row",
   "og:type":"article",
   "og:url":"http://www.guardian.co.uk/politics/2013/jul/21/tory-strategist-lynton-crosby-lobbying",
   "resourceName":"tory-strategist-lynton-crosby-lobbying",
   "title":"Tory strategist Lynton Crosby in new lobbying row | Politics | The Guardian",
   "Twitter:app:id:googleplay":"com.guardian",
   "Twitter:app:id:iphone":409128287,
   "Twitter:app:name:googleplay":"The Guardian",
   "Twitter:app:name:iphone":"The Guardian",
   "Twitter:app:url:googleplay":"guardian://www.guardian.co.uk/politics/2013/jul/21/tory-strategist-lynton-crosby-lobbying",
   "Twitter:card":"summary_large_image",
   "Twitter:site":"@guardian"
}
2
sebilasse

Fonction intégrée facile et php.

http://php.net/manual/en/function.get-meta-tags.php

1
Jay Dave

Obtenir les balises META à partir d'url, exemple de fonction php

function get_meta_tags ($url){
         $html = load_content ($url,false,"");
         print_r ($html);
         preg_match_all ("/<title>(.*)<\/title>/", $html["content"], $title);
         preg_match_all ("/<meta name=\"description\" content=\"(.*)\"\/>/i", $html["content"], $description);
         preg_match_all ("/<meta name=\"keywords\" content=\"(.*)\"\/>/i", $html["content"], $keywords);
         $res["content"] = @array("title" => $title[1][0], "descritpion" => $description[1][0], "keywords" =>  $keywords[1][0]);
         $res["msg"] = $html["msg"];
         return $res;
}

Exemple:

print_r (get_meta_tags ("bing.com") );

Obtenir les balises Meta php

1
x3m-bymer

De nos jours, la plupart des sites ajoutent des balises méta sur leurs sites, fournissant des informations sur leur site ou une page d'article particulière. Tels que des sites d'actualités ou de blogs.

J'ai créé une méta-API qui vous donne les métadonnées requises telles que OpenGraph, Schema.Org, etc.

Découvrez-le - https://api.sakiv.com/docs

1
sakiv
<?php 

// ------------------------------------------------------ 

function curl_get_contents($url) {

    $timeout = 5; 
    $useragent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0'; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_USERAGENT, $useragent); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
    $data = curl_exec($ch); 
    curl_close($ch); 

    return $data; 
}

// ------------------------------------------------------ 

function fetch_meta_tags($url) { 

    $html = curl_get_contents($url); 
    $mdata = array(); 

    $doc = new DOMDocument();
    $doc->loadHTML($html);

    $titlenode = $doc->getElementsByTagName('title'); 
    $title = $titlenode->item(0)->nodeValue;

    $metanodes = $doc->getElementsByTagName('meta'); 
    foreach($metanodes as $node) { 
    $key = $node->getAttribute('name'); 
    $val = $node->getAttribute('content'); 
    if (!empty($key)) { $mdata[$key] = $val; } 
    }

    $res = array($url, $title, $mdata); 

    return $res;
}

// ------------------------------------------------------ 

?>
1
sbmark

Comme cela a déjà été dit, cela peut résoudre le problème:

$url='http://stackoverflow.com/questions/3711357/get-title-and-meta-tags-of-external-site/4640613';
$meta=get_meta_tags($url);
echo $title=$meta['title'];

//php - Get Title and Meta Tags of External site - Stack Overflow
0
Roger

Réponse améliorée de @shamittomar ci-dessus pour obtenir les balises méta (ou celle spécifiée à partir d'une source HTML)

Peut être encore amélioré ... la différence avec le get_meta_tags par défaut de php est qu'il fonctionne même s'il y a une chaîne unicode

function getMetaTags($html, $name = null)
{
    $doc = new DOMDocument();
    try {
        @$doc->loadHTML($html);
    } catch (Exception $e) {

    }

    $metas = $doc->getElementsByTagName('meta');

    $data = [];
    for ($i = 0; $i < $metas->length; $i++)
    {
        $meta = $metas->item($i);

        if (!empty($meta->getAttribute('name'))) {
            // will ignore repeating meta tags !!
            $data[$meta->getAttribute('name')] = $meta->getAttribute('content');
        }
    }

    if (!empty($name)) {
        return !empty($data[$name]) ? $data[$name] : false;
    }

    return $data;
}
0
dav

J'ai fait ce petit paquet de compositeur basé sur la réponse la plus haute: https://github.com/diversen/get-meta-tags

composer require diversen/get-meta-tags

Et alors: 

use diversen\meta;

$m = new meta();

// Simple usage, get's title, description, and keywords by default
$ary = $m->getMeta('https://github.com/diversen/get-meta-tags');
print_r($ary);

// With more params
$ary = $m->getMeta('https://github.com/diversen/get-meta-tags', array ('description' ,'keywords'), $timeout = 10);
print_r($ary);

Il nécessite CURL et DOMDocument, en tant que réponse principale - et est construit dans le sens de la procédure, mais dispose d'une option permettant de définir le délai d'expiration du curl (et d'obtenir toutes sortes de balises méta). 

0
dennis

Si vous travaillez avec PHP, consultez les packages Pear sur pear.php.net et voyez si vous trouvez quelque chose d’utile pour vous. J'ai utilisé les packages RSS de manière efficace et cela fait gagner beaucoup de temps, à condition que vous puissiez suivre comment ils implémentent leur code via leurs exemples.

Jetez un coup d'œil à Sax 3 et voyez s'il répond à vos besoins. Sax 3 n'est plus mis à jour mais cela pourrait être suffisant.

0
Geekster

Ne devrions-nous pas utiliser OG?

La réponse choisie est bonne mais ne fonctionne pas lorsqu'un site est redirigé (très commun!) Et ne renvoie pas de balises OG, qui sont le nouveau standard de l'industrie . Voici une petite fonction qui est un peu plus utilisable en 2018. Elle essaie d'obtenir des balises OG et retombe dans les balises méta si elle ne les accepte pas:

function getSiteOG( $url, $specificTags=0 ){
    $doc = new DOMDocument();
    @$doc->loadHTML(file_get_contents($url));
    $res['title'] = $doc->getElementsByTagName('title')->item(0)->nodeValue;

    foreach ($doc->getElementsByTagName('meta') as $m){
        $tag = $m->getAttribute('name') ?: $m->getAttribute('property');
        if(in_array($tag,['description','keywords']) || strpos($tag,'og:')===0) $res[str_replace('og:','',$tag)] = $m->getAttribute('content');
    }
    return $specificTags? array_intersect_key( $res, array_flip($specificTags) ) : $res;
}

/////////////
//SAMPLE USE:
print_r(getSiteOG("http://www.stackoverflow.com")); //note the incorrect url

/////////////
//OUTPUT:
Array
(
    [title] => Stack Overflow - Where Developers Learn, Share, & Build Careers
    [description] => Stack Overflow is the largest, most trusted online community for developers to learn, shareâ âtheir programming âknowledge, and build their careers.
    [type] => website
    [url] => https://stackoverflow.com/
    [site_name] => Stack Overflow
    [image] => https://cdn.sstatic.net/Sites/stackoverflow/img/[email protected]?v=73d79a89bded
)
0
cronoklee

Cela fonctionne différemment et j'ai pensé le partager. Moins de code que d’autres et je l’ai trouvé ici . J'ai ajouté quelques éléments pour lui permettre de charger la méta de page sur laquelle vous vous trouvez au lieu d'une certaine page. Je voulais que cela copie automatiquement le titre et la description de la page par défaut dans les balises og.

Pour quelque raison que ce soit, quelle que soit la méthode choisie (différents scripts), la page se charge très lentement en ligne mais instantané sur wamp Je ne sais pas pourquoi alors je vais probablement avec un boîtier car le site n’est pas énorme.

<?php
$url = 'http://sitename.com'.$_SERVER['REQUEST_URI'];
$fp = fopen($url, 'r');

$content = "";

while(!feof($fp)) {
    $buffer = trim(fgets($fp, 4096));
    $content .= $buffer;
}

$start = '<title>';
$end = '<\/title>';

preg_match("/$start(.*)$end/s", $content, $match);
$title = $match[1];

$metatagarray = get_meta_tags($url);
$description = $metatagarray["description"];

echo "<div><strong>Title:</strong> $title</div>";
echo "<div><strong>Description:</strong> $description</div>";
?>

et dans l'en-tête HTML

<meta property="og:title" content="<?php echo $title; ?>" />
<meta property="og:description" content="<?php echo $description; ?>" />
0
e11world