zoukankan      html  css  js  c++  java
  • java使用Rome解析Rss的实例

    Rome简介

    Rome是为RSS聚合而开发的开源包,它可以支持0.91、0.92、0.93、0.94、1.0、2.0,可以说rss的版本基本上都支持了。

    Rss简介

    RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容),通常被用于新闻和其他按顺序排列的网站,例如Blog。
    RSS就是一种用来分发和汇集网页内容的XML格式!
    RSS =Really Simple Syndication(真正简单的聚合 )或Rich Site Summary(丰富站点摘要 )
    Rss目前已经被广泛的应用 也是xml应用中的最成功的一项。
    RSS 没有统一标准,目前被使用的版本主要有0.91、1.0、2.0 

    RSS的理解

    拿一个新闻网站来说,如果这个网站使用了RSS技术,也即表示这个网站按照RSS标准将其新闻罗列出来,生成一个RSS文件通常称为(RSS Feed,其实也就是一个*.xml文件)。其他网站或个人就订阅该新闻网站的新闻 ,其实也就是读取了新闻网站提供的RSS文件,既然说是”订阅“即表示这个过程是动态的,即主要体现在新闻网站上的内容更新了,浏览者也同时得到了更新后的内容。当然这要借助工具。
    目的及作用
    网站内容资源共享
    可以自由选择想要浏览的新闻
    不用一个网站一个网站,一个网页一个网页去逛了。只要这将你需要的内容订阅在一个RSS阅读器中,这些内容就会自动出现你的阅读器里,你也不必为了一个急切想知道的消息而不断的刷新网页,因为一旦有了更新,RSS阅读器就会自己通知你!
    RSS的联合(Syndication)
    发布一个RSS文件(一般称为RSS Feed)后,这个RSS Feed中包含的信息就能直接被其他站点调用,而且由于这些数据都是标准的XML格式,所以也能在其他的终端和服务中使用,如PDA、手机、邮件列表等。而且一个网站联盟(比如专门讨论旅游的网站系列)也能通过互相调用彼此的RSS Feed自动的显示网站联盟中其他站点上的最新信息,这就叫着RSS的联合。
    这种联合就导致一个站点的内容更新越及时、RSS Feed被调用的越多,该站点的知名度就会越高,从而形成一种良性循环 
    RSS的聚合(Aggregation)
    所谓RSS聚合,就是通过软件工具的方法从网络上搜集各种RSS Feed并在一个界面中提供给读者进行阅读。这些软件可以是在线的WEB工具 也可以是客户端软件

    Rss浏览
    RSS是一个纯xml文件,将RSS里的新闻友好的显示出来就要借助于RSS阅读器
    RSS阅读器其实就是一个客户端软件或内嵌程序,将各个新闻站点提供的xml文件(RSS Feed)中内容读取出来,将所有新闻分门别类的显示在软件中。分类管理也就是所谓的频道管理。

    Rss文件格式
    下面是一个Rss文件(*.xml),里面的注释是自己加的,<!-- 和-->之间为注释。
    <?xml version="1.0" encoding="utf-8" ?> 
    <!-- 声明当前文件为xml文档【必】
      --> 
    <rss version="2.0">
    <!-- 声明当前文件内容为rss格式文件,属性version(必须)指定当前rss版本【必】
      --> 
    <channel>
    <!-- 固有节点【必】
      --> 
      <title>新闻中心-国内焦点新闻</title> 
    <!-- 对网站和当前RSS 文件的简短描述【必】
      --> 
    <image>
    <!-- 为当前RSS添加图片
      --> 
      <title>新闻中心-国内焦点</title> 
    <!-- 图片标题对图片的简单描述
      --> 
      <link>http://news.sina.com.cn/china</link> 
    <!-- 网站链接地址
      --> 
      <url>http://image2.sina.com.cn/dy/gn/in10.jpg</url> 
    <!-- 图片的链接地址
      --> 
      </image>
      <description>国内焦点新闻列表</description> 
    -<!-- 对当前RSS文件的描述【必】
      --> 
      <link>http://news.sina.com.cn/china/index.shtml</link> 
    <!-- 网站主页链接【必】
      --> 
      <language>zh-cn</language> 
    <!-- 当前RSS使用的语言
      --> 
      <generator>WWW.SINA.COM.CN</generator> 
    <!-- 当RSS文件为自动创建时多存在此节点(RSS文件由什么创建)
      --> 
      <ttl>5</ttl> 
    <!-- (ttl = time to live) 在刷新前当前RSS在cache中可以保存多长时间(分钟)
      --> 
      <copyright>Copyright 1996 - 2005 SINA Inc. All Rights Reserved</copyright> 
    <!-- 声明版权
      --> 
      <pubDate>Wed, 26 Apr 2006 01:45:05 GMT</pubDate> 
    <!-- 当前RSS最后发布的时间
      --> 
      <category /> 
    <!-- 声明当前RSS内容的种类
      --> 
    <item>
    <!-- 一条信息
      --> 
      <title>最高检:严惩公务员利用审批等权力索贿受贿</title> 
    <!-- 新闻标题【必】
      --> 
      <link>http://news.sina.com.cn/c/l/2006-04-26/08029720281.shtml</link> 
    <!-- 新闻链接【必】
      --> 
      <author>WWW.SINA.COM.CN</author> 
    <!-- 新闻作者
      --> 
      <guid>http://news.sina.com.cn/c/l/2006-04-26/08029720281.shtml</guid> 
    <!-- guid>GUID=Globally Unique Identifier 为当前新闻指定一个全球唯一标示
      --> 
      <category>国内焦点新闻</category> 
    <!-- 新闻种类
      --> 
      <pubDate>Wed, 26 Apr 2006 00:02:53 GMT</pubDate> 
    <!-- 新闻最后发布时间
      --> 
      <comments /> 
    <!-- 新闻注释
      --> 
      <description>新华网沈阳4月25日电 (记者 杨维汉、范春生) 最高人民检察院常务副检察长张耕说,对于国家公务员在商业活动中利用职权谋取非法利益、索贿受贿的案件,必须发现一起,坚决查处一起。特别是对国家公务员利用行政审批权、行政执法权和司法权执法犯法、贪赃枉法、索贿受贿,构成犯....</description> 
    <!-- 新闻的简单描述【必】
      --> 
      </item>
     </channel>
     </rss>

    第一行 声明当前文件是xml文档
    第二行声明当前文件内容为rss格式文件,属性version(必须)指定当前rss版本为2.0
     <channel>节点为Rss文档的固有节点,必须,无属性。
    <item> 节点中即纪录了当前RSS Feed中要显示的内容。一个RSS文件中通常包含多个<item>节点
    <channel>节点
    必须节点
    <title> 对网站和当前RSS 文件的简短描述
    <link>  网站主页链接
    <description> 对当前RSS文件的描述
    可选节点
    <image>  为当前RSS添加图片
    <language> 当前RSS使用的语言
    <generator>当RSS文件为自动创建时多存在此节点(RSS文件由什么创建)
    <ttl>(ttl = time to live) 在刷新前当前RSS在cache中可以保存多长时间(分钟)
    <copyright>声明版权
    <pubDate> 当前RSS最后发布的时间
    <category>声明当前RSS内容的种类
     等等
    <item>节点
    <item>  纪录一条信息(新闻),只包含这条新闻的简单信息,一个RSS文件中包含几条新闻就会有几个<item>
    必须节点
    <title> 新闻标题
     <link>  新闻链接
    <description>  新闻的简单描述
    可选节点
    <author> 当前新闻的作者
    <guid>GUID=Globally Unique Identifier 为当前新闻指定一个全球唯一标示
    <category>当前新闻的类别
    <pubDate>当前新闻的最后发布时间
    <comments>当前新闻的注释
    等等

    附上实例源码:

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.zip.GZIPInputStream;
    
    import com.sun.syndication.feed.rss.Channel;
    import com.sun.syndication.feed.rss.Description;
    import com.sun.syndication.feed.rss.Guid;
    import com.sun.syndication.feed.rss.Item;
    import com.sun.syndication.feed.synd.SyndEntry;
    import com.sun.syndication.feed.synd.SyndFeed;
    import com.sun.syndication.io.FeedException;
    import com.sun.syndication.io.SyndFeedInput;
    import com.sun.syndication.io.WireFeedOutput;
    import com.sun.syndication.io.XmlReader;
    
    //http://rss.webofknowledge.com/rss?e=4f1b64b6b221ea05&c=8c6909b93bf3eb38a2066a826b61a412
    public class Test {
        public static void main(String[] args) {
            try {
                // parseXml(new
                // URL("http://rss.webofknowledge.com/rss?e=4f1b64b6b221ea05&c=8c6909b93bf3eb38a2066a826b61a412"));
                parseXml(new URL("http://127.0.0.1:8080/xd/rss?q=java&t=atom&h=50&s=50"));
                String xml=createXml();
                parseString(xml);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        private static void parseString(String xml) throws Exception {
        
            SyndFeedInput input = new SyndFeedInput();
            SyndFeed feed = null;
            ByteArrayInputStream inputStream=new ByteArrayInputStream(xml.getBytes("UTF-8"));
            feed = input.build(new XmlReader(inputStream));
            List entries = feed.getEntries();// 得到所有的标题<title></title>
            for (int i = 0; i < entries.size(); i++) {
                SyndEntry entry = (SyndEntry) entries.get(i);
                System.out.println(entry.getTitle());
            }
            System.out.println("feed size:" + feed.getEntries().size());
        }
    
        /**
         * 根据链接地址得到数据
         */
        public static void parseXml(URL url) throws IllegalArgumentException,
                FeedException {
            try {
                SyndFeedInput input = new SyndFeedInput();
                SyndFeed feed = null;
                URLConnection conn;
                conn = url.openConnection();
                String content_encoding = conn.getHeaderField("Content-Encoding");
                if (content_encoding != null && content_encoding.contains("gzip")) {
                    System.out.println("conent encoding is gzip");
                    GZIPInputStream gzin = new GZIPInputStream(
                            conn.getInputStream());
                    feed = input.build(new XmlReader(gzin));
                } else {
                    feed = input.build(new XmlReader(conn.getInputStream()));
                }
    
                List entries = feed.getEntries();// 得到所有的标题<title></title>
                for (int i = 0; i < entries.size(); i++) {
                    SyndEntry entry = (SyndEntry) entries.get(i);
                    System.out.println(entry.getTitle());
                }
                System.out.println("feed size:" + feed.getEntries().size());
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
        
        public static String createXml() throws Exception {      
            /* 根据Channel源码提供的英文,Channel对象有两个构造器,一个默认的无参构造器用于clone对象,一个是有参的    
            * 我们自己指定的必须使用有参数的(因为我们需要许可证),指构造方法必须要创建一个type(版本),这个type不能随便写,必须要以rss_开头的版本号    
            * Licensed under the Apache License, Version 2.0 (the "License");    
            * 因为当前版本是2.0,所以就是rss_2.0,必须是rss_2.0否则会抛异常,该源码中写的已经很明白。    
            */     
           Channel channel = new Channel("rss_2.0");      
           channel.setTitle("channel标题");//网站标题      
            channel.setDescription("channel的描述");//网站描述      
            channel.setLink("www.shlll.net");//网站主页链接      
            channel.setEncoding("utf-8");//RSS文件编码      
            channel.setLanguage("zh-cn");//RSS使用的语言      
            channel.setTtl(5);//time to live的简写,在刷新前当前RSS在缓存中可以保存多长时间(分钟)      
            channel.setCopyright("版权声明");//版权声明      
            channel.setPubDate(new Date());//RSS发布时间      
            List<Item> items = new ArrayList<Item>();//这个list对应rss中的item列表                
            Item item = new Item();//新建Item对象,对应rss中的<item></item>      
           item.setAuthor("hxliu");//对应<item>中的<author></author>      
           item.setTitle("新闻标题");//对应<item>中的<title></title>      
           item.setGuid(new Guid());//GUID=Globally Unique Identifier 为当前新闻指定一个全球唯一标示,这个不是必须的      
            item.setPubDate(new Date());//这个<item>对应的发布时间      
            item.setComments("注释");//代表<item>节点中的<comments></comments>      
            //新建一个Description,它是Item的描述部分      
            Description description = new Description();      
           description.setValue("新闻主题");//<description>中的内容      
            item.setDescription(description);//添加到item节点中      
            items.add(item);//代表一个段落<item></item>,      
            channel.setItems(items);      
            //用WireFeedOutput对象输出rss文本      
            WireFeedOutput out = new WireFeedOutput();      
            try {      
                String xml=out.outputString(channel);
                System.out.println(xml); 
                return xml;
            } catch (IllegalArgumentException e) {      
                e.printStackTrace();      
            } catch (FeedException e) {      
                e.printStackTrace();      
            }
            return null;
        }    
    }
    import java.net.URL;
    import java.util.List;
    
    import com.sun.syndication.feed.synd.SyndCategory;
    import com.sun.syndication.feed.synd.SyndContent;
    import com.sun.syndication.feed.synd.SyndEnclosure;
    import com.sun.syndication.feed.synd.SyndEntry;
    import com.sun.syndication.feed.synd.SyndFeed;
    import com.sun.syndication.io.SyndFeedInput;
    import com.sun.syndication.io.XmlReader;
    //http://zmfkplj.iteye.com/blog/461398
    public class TestParse {
        public static void main(String[] args) {
            TestParse test = new TestParse();
            test.parseRss();
        }
        public void parseRss() {
            //String rss = "http://news.baidu.com/n?cmd=1&class=civilnews&tn=rss&sub=0]http://news.baidu.com/n?cmd=1&class=civilnews&tn=rss&sub=0";
            String rss = "http://rss.sina.com.cn/ent/hot_roll.xml";    
            try {
                URL url = new URL(rss);
                // 读取Rss源   
                XmlReader reader = new XmlReader(url);        
                System.out.println("Rss源的编码格式为:" + reader.getEncoding());
                SyndFeedInput input = new SyndFeedInput();
                // 得到SyndFeed对象,即得到Rss源里的所有信息   
                SyndFeed feed = input.build(reader);
                //System.out.println(feed);            
                // 得到Rss新闻中子项列表   
                List entries = feed.getEntries();
                // 循环得到每个子项信息   
                for (int i = 0; i < entries.size(); i++) {
                    SyndEntry entry = (SyndEntry) entries.get(i);                                
                    // 标题、连接地址、标题简介、时间是一个Rss源项最基本的组成部分   
                    System.out.println("标题:" + entry.getTitle());
                    System.out.println("连接地址:" + entry.getLink());
                    SyndContent description = entry.getDescription();
                    System.out.println("标题简介:" + description.getValue());
                    System.out.println("发布时间:" + entry.getPublishedDate());                                
                    // 以下是Rss源可先的几个部分   
                    System.out.println("标题的作者:" + entry.getAuthor());                
                    // 此标题所属的范畴   
                    List categoryList = entry.getCategories();
                    if (categoryList != null) {
                        for (int m = 0; m < categoryList.size(); m++) {
                            SyndCategory category = (SyndCategory) categoryList.get(m);
                            System.out.println("此标题所属的范畴:" + category.getName());
                        }
                    }                            
                    // 得到流媒体播放文件的信息列表   
                    List enclosureList = entry.getEnclosures();
                    if (enclosureList != null) {
                        for (int n = 0; n < enclosureList.size(); n++) {
                            SyndEnclosure enclosure = (SyndEnclosure) enclosureList.get(n);
                            System.out.println("流媒体播放文件:" + entry.getEnclosures());
                        }
                    }
                    System.out.println();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    附上源码下载:http://download.csdn.net/detail/earbao/7540321

  • 相关阅读:
    Xshell学习第九课:数组与字符串
    Xshell学习第八课:函数
    Xshell学习第七课:sed语句
    Xshell学习第六课:read与for语句循环
    Xshell学习第五课:if判断语句
    Xshell学习第四课:grep与正则表达式
    Xshell学习第三课:编程原理
    Xshell学习第二课:重定向和管道符
    iOS中坐标转换
    iOS工作笔记(十五)
  • 原文地址:https://www.cnblogs.com/zuge/p/6297231.html
Copyright © 2011-2022 走看看