63

我想尝试弄清楚如何获得

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

即使它以任何顺序排列,我也听说过 PHP Simple HTML DOM Parser,但我并不想使用它。除了使用 PHP Simple HTML DOM Parser 之外,是否有可能提供解决方案。

preg_match如果它是无效的 HTML,将无法做到这一点?

cURL 可以用 preg_match 做这样的事情吗?

Facebook 会做这样的事情,但可以通过以下方式正确使用:

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

我想要这样的东西,以便当有人发布链接时,它应该检索标题和元标记。如果没有元标记,则它会被忽略,或者用户可以自己设置(但我稍后会自己设置)。

4

21 回答 21

176

这是应该的方式:

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";
于 2010-09-14T17:54:59.787 回答
41
<?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
?>
于 2012-03-15T01:02:59.393 回答
11

get_meta_tags将帮助您解决除标题之外的所有问题。要获得标题,只需使用正则表达式。

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

希望有帮助。

于 2011-01-09T17:34:21.587 回答
8

get_meta_tags不适用于标题。

只有具有名称属性的元标记,例如

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

将被解析。

于 2012-05-05T13:51:33.513 回答
6

PHP的原生函数:get_meta_tags()

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

于 2011-12-19T05:34:36.010 回答
5

不幸的是,内置的 php 函数 get_meta_tags() 需要 name 参数,而某些网站,例如 twitter 则将其关闭以支持 property 属性。此函数混合使用正则表达式和 dom 文档,将从网页返回一个键控元标记数组。它检查名称参数,然后检查属性参数。这已经在 instragram、pinterest 和 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;
}
于 2015-10-27T19:25:33.793 回答
5

我们不应该使用OG吗?

选择的答案很好,但在重定向站点时不起作用(非常常见!),并且不返回OG 标签,这是新的行业标准。这是一个在 2018 年更有用的小功能。它会尝试获取 OG 标签,如果无法获取,则回退到元标签:

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 USAGE:
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/apple-touch-icon@2.png?v=73d79a89bded
)
于 2018-09-07T08:50:37.283 回答
4

最好的办法是咬紧牙关使用 DOM 解析器——这是做这件事的“正确方法”。从长远来看,它会为您节省更多的时间,而不是学习如何。众所周知,使用 Regex 解析 HTML 是不可靠的并且不能容忍特殊情况。

于 2010-09-14T17:31:57.970 回答
4

一个了解如何检索 og:tags、title 和 description 的简单函数,请自行调整

function read_og_tags_as_json($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);

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

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

    // fecth <title>
    $res['title'] = $doc->getElementsByTagName('title')->item(0)->nodeValue;

    // fetch og:tags
    foreach( $doc->getElementsByTagName('meta') as $m ){

          // if had property
          if( $m->getAttribute('property') ){

              $prop = $m->getAttribute('property');

              // here search only og:tags
              if( preg_match("/og:/i", $prop) ){

                  // get results on an array -> nice for templating
                  $res['og_tags'][] =
                  array( 'property' => $m->getAttribute('property'),
                          'content' => $m->getAttribute('content') );
              }

          }
          // end if had property

          // fetch <meta name="description" ... >
          if( $m->getAttribute('name') == 'description' ){

            $res['description'] = $m->getAttribute('content');

          }


    }
    // end foreach

    // render JSON
    echo json_encode($res, JSON_PRETTY_PRINT |
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

}

返回此页面(可能有更多信息):

{
    "title": "php - Getting title and meta tags from external website - Stack Overflow",
    "og_tags": [
        {
            "property": "og:type",
            "content": "website"
        },
        {
            "property": "og:url",
            "content": "https://stackoverflow.com/questions/3711357/getting-title-and-meta-tags-from-external-website"
        },
        {
            "property": "og:site_name",
            "content": "Stack Overflow"
        },
        {
            "property": "og:image",
            "content": "https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon@2.png?v=73d79a89bded"
        },
        {
            "property": "og:title",
            "content": "Getting title and meta tags from external website"
        },
        {
            "property": "og:description",
            "content": "I want to try figure out how to get the\n\n&lt;title&gt;A common title&lt;/title&gt;\n&lt;meta name=\"keywords\" content=\"Keywords blabla\" /&gt;\n&lt;meta name=\"description\" content=\"This is the descript..."
        }
    ]
}
于 2020-05-26T05:43:54.933 回答
3

我们通过 php(命令行实用程序)使用Apache Tika和 -j for 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' );
?>

这是随机监护人文章的示例输出

{
   "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"
}
于 2013-07-21T21:42:48.350 回答
2

从url获取meta标签,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;
}

例子:

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

获取元标签 php

于 2012-09-06T16:45:51.313 回答
2

Easy 和 php 的内置函数。

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

于 2013-01-07T07:53:58.550 回答
2

我的解决方案(改编自 cronoklee 和 shamittomar 的部分帖子)所以我可以从任何地方调用它并获得 JSON 返回。可以很容易地解析成任何内容。

<?php
header('Content-type: application/json; charset=UTF-8');

if (!empty($_GET['url']))
{
    file_get_contents_curl($_GET['url']);
}
else
{
    echo "No Valid URL Provided.";
}


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);

    echo json_encode(getSiteOG($data), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
}

function getSiteOG( $OGdata){
    $doc = new DOMDocument();
    @$doc->loadHTML($OGdata);
    $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)] = utf8_decode($m->getAttribute('content'));

    }

    return $res;
}
?>
于 2020-03-25T03:11:14.977 回答
1

如果您正在使用 PHP,请查看pear.php.net上的 Pear 包,看看您是否发现任何对您有用的东西。我已经有效地使用了 RSS 包,它节省了很多时间,前提是您可以通过他们的示例了解他们如何实现他们的代码。

具体看一下Sax 3,看看它是否能满足您的需求。Sax 3 不再更新,但它可能就足够了。

于 2010-09-14T18:07:09.010 回答
1

正如已经说过的,这可以解决问题:

$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
于 2012-04-29T20:25:00.430 回答
1
<?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;
}

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

?>
于 2014-02-28T18:11:53.493 回答
1

我根据最佳答案制作了这个小作曲家包:https ://github.com/diversen/get-meta-tags

composer require diversen/get-meta-tags

进而:

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);

它需要 CURL 和 DOMDocument 作为最佳答案 - 并且内置,但可以选择设置 curl 超时(以及获取各种元标记)。

于 2016-11-07T17:48:57.793 回答
1

现在,大多数网站都会在其网站上添加元标记,以提供有关其网站或任何特定文章页面的信息。例如新闻或博客网站。

我创建了一个 Meta API,它为您提供所需的元数据,如 OpenGraph、Schema.Org 等。

看看 - https://api.sakiv.com/docs

于 2017-03-19T19:53:05.073 回答
1

我有这个以不同的方式工作,并认为我会分享它。比其他人少的代码,在这里找到了。我添加了一些东西来让它加载你所在的页面元而不是某个页面。我希望它自动将默认页面标题和描述复制到 og 标签中。

但是,出于某种原因,无论我尝试了哪种方式(不同的脚本),页面在线加载速度都非常慢,但在 wamp 上会立即加载。不知道为什么,所以我可能会使用开关盒,因为该站点并不大。

<?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>";
?>

并在 HTML 标头中

<meta property="og:title" content="<?php echo $title; ?>" />
<meta property="og:description" content="<?php echo $description; ?>" />
于 2018-06-21T23:36:05.747 回答
1

改进了上面@shamittomar 的答案以获取元标记(或来自 html 源的指定标记)

可以进一步改进...与 php 的默认 get_meta_tags 的区别在于,即使存在 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;
}
于 2018-07-17T16:40:12.043 回答
0

这是获取页面 META 详细信息的 PHP 简单 DOM HTML 类的两行代码。

$html = file_get_html($link);
$meat_description = $html->find('head meta[name=description]', 0)->content;
$meat_keywords = $html->find('head meta[name=keywords]', 0)->content;
于 2013-12-28T11:39:00.167 回答