2008-10-30 65 views
118

我目前使用的是Magpie RSS,但當RSS或Atom提要不正常形成時,它有時會失效。用PHP解析RSS和Atom提要有沒有其他選擇?使用PHP解析RSS/Atom提要的最佳方式

+1

有一個問題這個請求大部分供稿閱讀器都使用php的核心XML讀取器,如果XML不像XML標準所要求的格式良好,它會崩潰,你可以看看那些不使用XML閱讀器並使用文本閱讀器的人,但是負載在服務器上會大幅增加。 我知道這是回答我只是讓人們意識到使用XML供稿閱讀器的缺點 – 2013-09-10 09:29:57

+1

永遠不要試圖解析無效的XML。責備來源。 – Lothar 2014-11-27 04:03:48

回答

28

你的其他選擇包括:

+4

Zend Feed http://framework.zend.com/manual/en/zend.feed.html – artur 2010-02-26 21:57:34

+173

我不喜歡這樣的「答案」,給出沒有任何評論的鏈接。看起來像谷歌,並鏈接到一些頂級的結果。特別是因爲提問者有一些RSS體驗,需要一個更好的解析器。 – 2011-07-30 13:49:34

+3

如果有人需要一點建議,Last RSS是上面列出的三個中最簡單的。只需要一個文件來「需要」,並且可以在5行內獲取RSS,並具有相當好的數組輸出。 – Raptor 2014-05-11 05:53:26

2

我用SimplePie解析一個谷歌閱讀器飼料,它的工作原理非常好,有一個體面的功能集。

當然,我還沒有用非完整的RSS/Atom提要對它進行測試,所以我不知道它如何處理這些問題,我假設Google的標準相當符合標準! :)

6

HTML Tidy庫能夠修復一些格式不正確的XML文件。在將它們傳遞給解析器之前,通過它來運行您的提要可能會有所幫助。

151

我一直使用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; 
    } 
} 
12

如果飼料沒有良好的XML,你應該拒絕它,沒有例外。您有權致電訂閱源創建者a bozo

否則你鋪平了道路混亂,HTML中結束了。

1

我個人使用BNC高級訂閱Parser-我喜歡的模板系統,這是非常容易使用

32

有了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); 
15

我想介紹的簡單腳本解析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++; 
}