代码之家  ›  专栏  ›  技术社区  ›  carson

用PHP解析RSS/Atom源的最佳方法[关闭]

  •  125
  • carson  · 技术社区  · 17 年前

    我正在使用 Magpie RSS 但当RSS或Atom提要没有很好地形成时,它有时会崩溃。用PHP解析RSS和Atom提要还有其他选择吗?

    10 回复  |  直到 9 年前
        1
  •  28
  •   josh3736    13 年前
        2
  •  158
  •   Brian Cline    12 年前

    我总是用 the SimpleXML functions built in to PHP 解析XML文档。它是为数不多的具有直观结构的通用解析器之一,这使得为一些特定的东西(比如RSS提要)构建一个有意义的类变得非常容易。此外,它还将检测XML警告和错误,一旦找到任何错误,您可以简单地通过类似于html-tidy(如ceejayoz所提到的)的东西运行源代码来清理并再次尝试。

    考虑使用simpleXML的这个非常粗糙、简单的类:

    class BlogPost
    {
        var $date;
        var $ts;
        var $link;
    
        var $title;
        var $text;
    }
    
    class BlogFeed
    {
        var $posts = array();
    
        function __construct($file_or_url)
        {
            $file_or_url = $this->resolveFile($file_or_url);
            if (!($x = simplexml_load_file($file_or_url)))
                return;
    
            foreach ($x->channel->item as $item)
            {
                $post = new BlogPost();
                $post->date  = (string) $item->pubDate;
                $post->ts    = strtotime($item->pubDate);
                $post->link  = (string) $item->link;
                $post->title = (string) $item->title;
                $post->text  = (string) $item->description;
    
                // Create summary as a shortened body and remove images, 
                // extraneous line breaks, etc.
                $post->summary = $this->summarizeText($post->text);
    
                $this->posts[] = $post;
            }
        }
    
        private function resolveFile($file_or_url) {
            if (!preg_match('|^https?:|', $file_or_url))
                $feed_uri = $_SERVER['DOCUMENT_ROOT'] .'/shared/xml/'. $file_or_url;
            else
                $feed_uri = $file_or_url;
    
            return $feed_uri;
        }
    
        private function summarizeText($summary) {
            $summary = strip_tags($summary);
    
            // Truncate summary line to 100 characters
            $max_len = 100;
            if (strlen($summary) > $max_len)
                $summary = substr($summary, 0, $max_len) . '...';
    
            return $summary;
        }
    }
    
        3
  •  36
  •   PJunior    12 年前

    使用4行,我将一个RSS导入到一个数组中。

    $feed = implode(file('http://yourdomains.com/feed.rss'));
    $xml = simplexml_load_string($feed);
    $json = json_encode($xml);
    $array = json_decode($json,TRUE);
    

    对于更复杂的解决方案

    $feed = new DOMDocument();
     $feed->load('file.rss');
     $json = array();
     $json['title'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
     $json['description'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
     $json['link'] = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('link')->item(0)->firstChild->nodeValue;
     $items = $feed->getElementsByTagName('channel')->item(0)->getElementsByTagName('item');
    
     $json['item'] = array();
     $i = 0;
    
     foreach($items as $key => $item) {
     $title = $item->getElementsByTagName('title')->item(0)->firstChild->nodeValue;
     $description = $item->getElementsByTagName('description')->item(0)->firstChild->nodeValue;
     $pubDate = $item->getElementsByTagName('pubDate')->item(0)->firstChild->nodeValue;
     $guid = $item->getElementsByTagName('guid')->item(0)->firstChild->nodeValue;
    
     $json['item'][$key]['title'] = $title;
     $json['item'][$key]['description'] = $description;
     $json['item'][$key]['pubdate'] = $pubDate;
     $json['item'][$key]['guid'] = $guid; 
     }
    
    echo json_encode($json);
    
        4
  •  17
  •   Vladimir Lukyanov    11 年前

    我想介绍一个简单的脚本来解析RSS:

    $i = 0; // counter
    $url = "http://www.banki.ru/xml/news.rss"; // url to parse
    $rss = simplexml_load_file($url); // XML parser
    
    // RSS items loop
    
    print '<h2><img style="vertical-align: middle;" src="'.$rss->channel->image->url.'" /> '.$rss->channel->title.'</h2>'; // channel title + img with src
    
    foreach($rss->channel->item as $item) {
    if ($i < 10) { // parse only 10 items
        print '<a href="'.$item->link.'">'.$item->title.'</a><br />';
    }
    
    $i++;
    }
    
        5
  •  12
  •   Kornel    17 年前

    如果提要不是格式良好的XML,那么应该拒绝它,没有异常。您有权呼叫订阅源创建者 a bozo .

    否则,您将铺平弄乱HTML的道路。

        6
  •  6
  •   ceejayoz    17 年前

    HTML整理库可以修复一些格式错误的XML文件。在将提要传递给解析器之前,运行这些提要可能会有所帮助。

        7
  •  2
  •   user7094    17 年前

    我用 SimplePie 要解析一个谷歌阅读器feed,它工作得很好,并且有一个不错的特性集。

    当然,我还没有用格式不好的RSS/Atom feeds测试过它,所以我不知道它是如何处理这些问题的,我假设Google是相当符合标准的!:)

        8
  •  1
  •   Adam    16 年前

    我个人使用BNC高级提要解析器-我喜欢非常容易使用的模板系统

        9
  •  1
  •   Thinol    11 年前

    PHP RSS阅读器- http://www.scriptol.com/rss/rss-reader.php -是一个完整但简单的解析器,被成千上万的用户使用…

        10
  •  -1
  •   Lucas    12 年前

    另一个伟大的自由解析器- http://bncscripts.com/free-php-rss-parser/ 它非常轻(只有3kb)而且使用简单!

    推荐文章