天天看點

Web版RSS閱讀器(三)——解析線上Rss訂閱

      上篇部落格《 Web版RSS閱讀器(二)——使用dTree樹形加載rss訂閱分組清單》已經寫到讀取rss訂閱清單了,今天就說一下,當擷取一條線上rss訂閱的資訊,怎麼去解析它,進而擷取文章或資訊。

      首先說一下rss的版本。很多人都說rss,但是有相當一部分人,都不知道rss居然不隻一種格式。我們常用的訂閱格式有Rss和Atom 2種格式。Rss有版本從v0.9一直到現在的v2.0,Atom最新的版本則是1.0。

      DeveloperWorks有一篇文章《使用 RSS 和 Atom 實作新聞聯合》提及兩者的相似點與不同點:

RSS 和 Atom 摘要的相似點

每個摘要檔案實際上代表一個通道。它包含通道标題、連結、描述、作者等等。通道資訊提供關于摘要的基本資訊。通道資訊之後是一些項。每項代表一篇可以從摘要閱讀器閱讀的真實的新聞或者文章。通常情況下,每項包含有标題、連結、更新時間和摘要資訊。

RSS 和 Atom 摘要的不同點

參考 RSS 2.0 and Atom 1.0, Compared,回顧 RSS 和 Atom 的不同點。
不同點 RSS 2.0 Atom 1.0
部署 RSS 2.0 得到廣泛部署。 Atom 1.0 還未得到廣泛部署。
規範 哈佛大學擁有版權并當機了 RSS 2.0 規範。 Atompub 工作組(屬于 IETF)就 Atom 1.0 規範達成一緻意見,并在将來有可能重新修訂。
所需内容 RSS 2.0 包含所需的摘要級别的标題、連結和描述。它不需要在摘要中出現的任何單獨項的字段。 Atom 1.0 包含摘要和條目所需的标題(可以為空)、惟一辨別和最後更新的時間戳。
有效負載(payload) RSS 2.0 可以包含普通文本或者轉義 HTML,但是不能分辨所提供的是兩個中的哪一個。 Atom 1.0 包含有效負載容器。
全部或者部分内容 RSS 2.0 有一個 

<description>

 元素,可以包含條目的全部文本或者大綱。它沒有用于辨別内容是否完全的内置方法。
Atom 1.0 提供單獨的 

<summary>

 和 

<content> 元素

。如果它是非文本的或者非本地的内容,出于可通路性的原因摘要将很好用。
自動發現 RSS 2.0 用不同的方法實作自動發現。 Atom 1.0 标準化自動發現。
提取和聚合 RSS 2.0 隻有一個可識别的形式:一個

<rss>

 文檔。
Atom 1.0 允許獨立的 Atom Entry 文檔,可以使用任何網絡協定傳輸;例如,XMPP。Atom 也支援聚合摘要,其中,條目指向它們來自的摘要,前提是如果它們将被包含到其他摘要中。
RSS 和 Atom 具有相似的基于 XML 的格式。它們的基本結構是相同的,隻在節點的表達式上有一點差別。

在Rss标準格式:

<!-- XML版本和字元集 -->
 <?xml version="1.0"?>
 <!-- RSS版本 -->
 <rss version="2.0">
 <!-- 以下為頻道資訊及新聞資訊或文章清單 -->
 <channel>
  <!-- 頻道總體資訊:開始 -->
  <!-- 頻道标題 -->
  <title>Lift Off News</title>
  <!-- 頻道連結的總位址 -->
  <link>http://liftoff.msfc.nasa.gov/</link>
  <!-- 頻道描述文字 -->
  <description>Liftoff to Space Exploration.</description>
  <!-- 頻道使用的語言(zh-cn表示簡體中文) -->
  <language>en-us</language>
  <!-- 頻道釋出的時間 -->
  <pubDate>Tue, 10 Jun 2003 04:00:00 GMT</pubDate>
  <!-- 頻道最後更新的時間-->
  <lastBuildDate>Tue, 10 Jun 2003 09:41:01 GMT</lastBuildDate>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <!-- 頻道生成器 -->
  <generator>Weblog Editor 2.0</generator>
  <ttl>5</ttl>
  <!-- 頻道總體資訊:結束 -->
  <!-- 每條RSS新聞資訊都包含在item節點中, -->
  <item>
  <!-- 新聞标題 -->
  <title>Star City</title>
  <!-- 新聞連結位址 -->
  <link>http://liftoff.msfc.nasa.gov/news/2013/news-starcity.asp</link>
  <!-- 新聞内容簡要描述 -->
  <description>How do Americans get ready to work with Russians aboard the
  International Space Station? They take a crash course in culture, language
  and protocol at Russia's Star City.</description>
  <!-- 新聞釋出時間 -->
  <pubDate>Tue, 03 Jun 2003 09:39:21 GMT</pubDate>
  <!-- 新聞目錄 -->
  <category>IT</category>
  <!-- 新聞作者 -->
  <author>bill</author>
  <guid>http://liftoff.msfc.nasa.gov/2003/06/03.html#item573</guid>
  </item>
  <!-- 第二條新聞資訊 -->
  <item>
  <title>Space Exploration</title>
  <link>http://liftoff.msfc.nasa.gov/</link>
  <description>Sky watchers in Europe, Asia, and parts of Alaska and Canada
  will experience a partial eclipse of the Sun on Saturday, May 31st.</description>
  Fri, 30 May 2003 11:06:42 GMT</pubDate>
  <guid>http://liftoff.msfc.nasa.gov/2003/05/30.html#item572</guid>
  </item>  
  </channel>
 </rss>
           

Atom 1.0的格式:

<?xml version="1.0" encoding="utf-8"?>
<!-- ATOM版本 -->
<feed xmlns="http://www.w3.org/2005/Atom"">
    <!-- 頻道标題 -->
 <title>Schema Web</title>
    <!-- 頻道連結的總位址 -->
 <link rel="alternate" type="text/html" href="http://stanzaweb.art/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" />
    <!-- 最新修改時間-->
 <modified>2004-06-01T10:11:12Z</modified>
    <!-- 頻道作者 -->
 <author>
        <!-- 昵稱 -->
  <name>Uche Ogbuji</name>
 </author>
    <!-- 以下是新聞資訊或文章清單 -->
 <entry>
    <!-- 新聞标題 -->
  <title>Welcome to Stanza Web</title>
    <!-- 新聞作者 -->
  <author>
          <!-- 作者昵稱 -->
   <name>龍軒</name>
         <!-- 首頁 -->
         <uri>http://www.cnblogs.com/longxuan/</uri>
  </author>
      <!-- 文章連接配接 -->
  <link rel="alternate" type="text/html" href="http://stanzaweb.art/2004-06-01/welcome" target="_blank" rel="external nofollow" />
      <!-- 最新修改時間 -->
  <modified>2004-06-01T10:11:12Z</modified>
      <!-- 文章内容 -->
  <content type="html">
   <div >
    <p>Welcome to
     <a href="http://stanzaweb.art/" target="_blank" rel="external nofollow"  target="_blank" rel="external nofollow" >Stanza Web</a>.
     Come back often to keep track of the best in modern poetry.
    </p>
    <p>This site is powered by
      <a href="http://atomenabled.org" target="_blank" rel="external nofollow" >Atom</a>
    </p>
   </div>
  </content>
 </entry>
</feed>
           

      大部分新聞或部落格網站都使用的是rss,當然Atom也占有部分市場。比如部落格園就是用的Atom,而CSDN則用的是RSS。

     了解了這些以後,就可以開始解析Rss了。

     在網上找了一下開源的包,選了2款常用的都實驗了一下,一個是Rome.jar,一個是rsslib4j.jar。二者的差別我就不多介紹了,有興趣了可以去百度一下。rsslib4j 小巧,相容性好,但是現在隻支援解析rss 0.9x ,1.0 和 2.0,暫時對于atom無能為力。rsslib4j的開源首頁:http://sourceforge.net/projects/rsslib4j/。有什麼需要的,可以在首頁進行下載下傳。

      在WebRoot/lib中引用rsslib4j-0.2.jar,在src的com.tgb.rssreader.manager包中建立一個類Rsslib4jReadRss,貼出代碼:

package com.tgb.rssreader.manager;

import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.gnu.stealthp.rsslib.RSSChannel;
import org.gnu.stealthp.rsslib.RSSHandler;
import org.gnu.stealthp.rsslib.RSSImage;
import org.gnu.stealthp.rsslib.RSSItem;
import org.gnu.stealthp.rsslib.RSSParser;

public class Rsslib4jReadRss {

    //這裡定義一個線上的rss摘要的位址(對應我的網易部落格) 
    public static final String remoteRSS="http://xiaoxian100.blog.163.com/rss"; 
 
    public static void main(String[] args) throws Exception { 
 
        // 讓RSSParser去解析線上的rss的url 
        RSSHandler remoteRSSHandler = new RSSHandler(); 
        URL url = new URL(remoteRSS);
        URLConnection feedUrl = url.openConnection();

        RSSParser.parseXmlFile(feedUrl.getURL(), remoteRSSHandler, false); 
        // 取得rss元素的資訊并且列印在控制台上 
        String remoteRSSInfo=Rsslib4jReadRss.getRSSInfo(remoteRSSHandler); 
        System.out.println("****************我的網易部落格的 rss資訊如下******************"); 
        System.out.println(remoteRSSInfo); 
        System.out.println("****************************************************"); 
        
 
    } 

	public static String getRSSInfo(RSSHandler handler) {

		StringBuffer rssInfo = new StringBuffer();

		// 取得rss提要的頻道資訊(Channel)
		RSSChannel channel = handler.getRSSChannel();

		// Part1: 分離出rss頻道的元資訊
		// (1)頻道的标題
		String titleInfo = channel.getTitle();
		// (2)頻道的連結資訊
		String linkInfo = channel.getLink();
		// (3)頻道的描述資訊
		String descriptionInfo = channel.getDescription();
		// (4)頻道使用的語言
		String languageInfo = channel.getLanguage();
		// (5)頻道版權資訊
		String copyrightInfo = channel.getCopyright();
		// (6)頻道的generator的資訊
		String generatorInfo = channel.getGenerator();
		// (7)頻道的image資訊
		RSSImage channelImage = channel.getRSSImage();
		String channelImageUrl = channelImage.getUrl();

		rssInfo.append("頻道标題: " + titleInfo + "\n");
		rssInfo.append("頻道相關Link資訊: " + linkInfo + "\n");
		rssInfo.append("頻道描述資訊: " + descriptionInfo + "\n");
		rssInfo.append("頻道使用的語言: " + languageInfo + "\n");
		rssInfo.append("頻道版權資訊: " + copyrightInfo + "\n");
		rssInfo.append("頻道産生器資訊: " + generatorInfo + "\n");
		rssInfo.append("頻道圖檔URL: " + channelImageUrl + "\n");

		//Part2: 分離出rss頻道的所有摘要(feed),這裡用item表示
		List channelItems = channel.getItems();
		int itemSize = channelItems.size();
		if (itemSize >= 1) {
			rssInfo.append("\n");
			rssInfo.append("一共有 " + itemSize + "個摘要在這個頻道中");
			rssInfo.append("\n");
			for (int i = 0; i < itemSize; i++) {
				int itemNo = i + 1;
				RSSItem item = (RSSItem) channelItems.get(i);

				rssInfo.append("\n");
				rssInfo.append("摘要" + itemNo + ":");

				// (1)摘要的作者
				String itemAuthor = item.getAuthor();
				// (2)摘要的标題
				String itemTitle = item.getTitle();
				// (3)摘要的描述
				String itemDescription = item.getDescription();
				// (4)摘要的連結
				String itemLink = item.getLink();
				// (5)摘要的釋出日期
				String itemPubDate = item.getPubDate();

				rssInfo.append("作者: " + itemAuthor + "\n");
				rssInfo.append("标題: " + itemTitle + "\n");
				rssInfo.append("描述: " + itemDescription + "\n");
				rssInfo.append("連結: " + itemLink + "\n");
				rssInfo.append("釋出日期: " + itemPubDate + "\n");

				rssInfo.append("\n");
			}
		}

		return rssInfo.toString();

	}

}
           

      由于文章太多,在Console中測試時,可能會看不到後面的效果,是以我隻讓程式讀取了一個文章摘要(for循環次數修改為1),效果圖如下:

Web版RSS閱讀器(三)——解析線上Rss訂閱

      在解析網易部落格時,還算勉強可以勝任,但是在解析CSDN部落格時,就會報錯"Server returned HTTP response code: 403 for URL: http://xxxxxx",這是因為CSDN部落格,拒絕java作為用戶端進行通路其伺服器。而且在解析個别資訊時,會出現null值。

      那怎麼辦呀?别着急,下篇博文,大家跟我一起修改rsslib4j,做自己的rsslib4j。敬請期待!

繼續閱讀