在上篇博文《Web版RSS阅读器(三)——解析在线Rss订阅》中,已经提到了遇到的问题,这里再详细说一下。

在解析rss格式的订阅时,遇到的最主要的问题是,出现了“Server returned HTTP response code: 403 for URL: http://xxxxxx”的错误,百度一下就知道,这是在网站访问中很常见的一个错误,服务器理解客户的请求,但拒绝处理它。即拒绝访问!接着查资料,得知某些服务器(比如CSDN博客)拒绝java作为客户端进行对其的访问,所以在解析时,会抛异常。

不让访问怎么办,别怕,我们上有政策,下有对策。通过设置User-Agent来欺骗服务器,从而访问服务器。

connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");    //用UA伪装访问连接对象

但是折腾了半天,发现只有修改rsslib4j.jar才能给连接对象设置UA。只好找源码修改一下了,N久之后,在Google Code上猎取到一个开源的项目newrsslib4j,它是在rsslib4j的基础上修改而来的,项目开源主页:http://code.google.com/p/newrsslib4j/。满怀欣喜的下载下来,结果发现,依旧有403的问题。一狠心,自己来做一个rsslib,然后就checkout了newrsslib4j的源码,自己动手改动。

1. 修改403 forbidden问题。

修改org.gnu.stealthp.rsslib包中的RssParser类的setXmlResource()方法,给URLConnection对象,添加UA。

  /*** Set rss resource by URL* @param ur the remote url* @throws RSSException*/public void setXmlResource(URL ur) throws RSSException{try{URLConnection con = u.openConnection();//-----------------------------//添加时间:2013-08-14 21:00:17//人员:@龙轩//博客:http://blog.csdn.net/xiaoxian8023//添加内容:由于服务器屏蔽java作为客户端访问rss,所以设置User-Agentcon.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");//-----------------------------con.setReadTimeout(10000);String charset = Charset.guess(ur);is = new InputSource (new UnicodeReader(con.getInputStream(),charset));if (con.getContentLength() == -1 && is == null){this.fixZeroLength();}}catch(IOException e){throw new RSSException("RSSParser::setXmlResource fails: "+e.getMessage());}}

修改org.mozilla.intl.chardet包中的Charset类的guess()方法,注释掉原来的InputStream对象,创建URLConnection,设置User-Agent,通过URLConnection对象创建InputStream :

 //judge from url  public static String guess(URL url) throws IOException {//-----------------------------//修改时间:2013-08-14 21:00:17//人员:@龙轩//博客:http://blog.csdn.net/xiaoxian8023//修改内容:注释InputStream,创建URLConnection,设置User-Agent,通过URLConnection对象创建InputStream//InputStream in = url.openStream();URLConnection con = url.openConnection();con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");InputStream in = con.getInputStream();//-----------------------------return guess(in);}

2. 添加获取文章摘要的方法

测试以后,发现Rss格式的订阅,居然没有提供一个获取内容摘要的方法。所以,继续修改。修改org.gnu.stealthp.rsslib包中的RssObject类,添加一个getSummary()方法,用来获取内容摘要:

  //-----------------------------------//添加时间:2013-08-14 19:32:15//人员:@龙轩//添加内容:添加getSummary()方法,返回文章摘要信息/*** Get the element's summary* @return the summary*/public String getSummary(){String summary = getDescription();if (summary.length() >= 300) {summary = summary.substring(0, 300);}String regEx_html = "\\s|<[^>]+>|&\\w{1,5};"; // 定义HTML标签和特殊字符的正则表达式Pattern pattern = Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(summary);summary = matcher.replaceAll(""); // 过滤script标签if (summary.length() >= 100) {summary = summary.substring(0, 100);}summary = summary + "...";return summary;}//添加结束-----------------------------------------------

3. 解决解析不完全问题
       网易博客可以很好的解析出博客的link,language等节点,但是csdn、某些新闻资讯网站则不行。花了很长的时间去找问题,终于在不经意间,发现网易的博客节点的排列顺序与别的不一样,link,language等节点排在image节点上面的,而csdn则是在image的下面(如图),程序在解析时,先解析channel下的节点,写入到channel中,读取到image,则标记解析channel的变量为false,然后开始解析image节点下的内容。解析完毕以后,又要去解析channel节点下的link时,channel标记已经为false了,不能再继续解析,所以总是返回null。

修改方案也很简单,就是所有标记解析channel为false的节点,在解析完毕该节点后,重新标记解析channel为true,这样就可以继续解析channel节点下的其他值 。具体修改操作:查看org.gnu.stealthp.rsslib包的RSSHandler类的startElement()方法,看看谁执行了 reading_chan = false; 这句代码。然后在endElement()方法中,重新设置 reading_chan = true; 即可:

  /*** Receive notification of the end of an element* @param uri The Namespace URI, or the empty string if the element has no Namespace URI or if Namespace processing is not being performed.* @param localName The local name (without prefix), or the empty string if Namespace processing is not being performed* @param qName The qualified name (with prefix), or the empty string if qualified names are not available*/public void endElement(String uri,String localName,String qName){String data = buff.toString().trim();if (qName.equals(current_tag)){data = buff.toString().trim();buff = new StringBuffer();}if (reading_chan)processChannel(qName,data);if (reading_item)processItem(qName,data);if (reading_image)processImage(qName,data);if (reading_input)processTextInput(qName,data);if (tagIsEqual(qName,CHANNEL_TAG)){reading_chan = false;chan.setSyndicationModule(sy);}if (tagIsEqual(qName,ITEM_TAG)){reading_item = false;//-----------------------------------------//添加时间:2013-08-14 21:00:17//人员:@龙轩//博客:http://blog.csdn.net/xiaoxian8023//添加内容:重新允许解析channelreading_chan = true;//添加结束---------------------------------chan.addItem(itm);}if (tagIsEqual(qName,IMAGE_TAG)){reading_image = false;//-----------------------------------------//添加时间:2013-08-14 21:00:17//人员:@龙轩//博客:http://blog.csdn.net/xiaoxian8023//添加内容:重新允许解析channelreading_chan = true;//添加结束---------------------------------chan.setRSSImage(img);}if (tagIsEqual(qName,SEQ_TAG)){reading_seq = false;chan.addRSSSequence(seq);}if (tagIsEqual(qName,TEXTINPUT_TAG)){reading_input = false;//-----------------------------------------//添加时间:2013-08-14 21:00:17//人员:@龙轩//博客:http://blog.csdn.net/xiaoxian8023//添加内容:重新允许解析channelreading_chan = true;//添加结束---------------------------------chan.setRSSTextInput(input);}}

至此,修改的就差不多了,打开一下org.javali.util.test包的RssNewsFetcher类,修改一下测试列表和方法:

package org.javali.util.test;import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;import org.gnu.stealthp.rsslib.RSSChannel;
import org.gnu.stealthp.rsslib.RSSException;
import org.gnu.stealthp.rsslib.RSSHandler;
import org.gnu.stealthp.rsslib.RSSItem;
import org.gnu.stealthp.rsslib.RSSParser;public class RssNewsFetcher {/*** rss订阅列表*/private final static String[] rssArr = new String[] {//"http://news.baidu.com/n?cmd=1&class=civilnews&tn=rss","http://xiaoxian100.blog.163.com/rss","http://blog.csdn.net/xiaoxian8023/rss/list" };/*** 测试解析rss订阅* @throws IOException*/public void testFetchRssNews() throws IOException {for (int i = 0; i < rssArr.length; i++) {try {//获取rss订阅地址URL url = new URL(rssArr[i]);RSSHandler handler = new RSSHandler();//解析rssRSSParser.parseXmlFile(url, handler, false);//获取Rss频道信息RSSChannel ch = handler.getRSSChannel();System.out.println("---------------------------------------------");System.out.println("博客标题:" + ch.getTitle());System.out.println("博客链接:" + ch.getLink());System.out.println("博客描述:" + ch.getDescription());System.out.println("博客语言:" + ch.getLanguage());System.out.println("发布时间:" + ch.getPubDate());System.out.println("图片地址:" +ch.getRSSImage().getUrl());System.out.println("图片指向:" +ch.getRSSImage().getLink());System.out.println("共有文章数目为:" + ch.getItems().size());
//              for(i=0;i<ch.getItems().size();i++){for(int j=0;j<1;j++){   //这里为了方便测试,只取一次循环,真实使用时,需选用上面那句代码RSSItem item = (RSSItem)ch.getItems().get(j);System.out.println("文章标题:" + item.getTitle());System.out.println("文章摘要:" + item.getSummary());//System.out.println("文章正文:" + item.getDescription());//这里为了演示方便,我取正文的前100个字符,真实使用时,需选用上面那句代码System.out.println("文章正文:" + item.getDescription().substring(0, 100));System.out.println("文章链接:" + item.getLink());System.out.println("发表时间:" + item.getPubDate());System.out.println("文章作者:" + item.getAuthor());System.out.println("最新修改:" + item.getDate());}} catch (MalformedURLException e) {e.printStackTrace();} catch (RSSException e) {e.printStackTrace();}}}public static void main(String[] args) throws IOException{RssNewsFetcher fetcher = new RssNewsFetcher();fetcher.testFetchRssNews();}}

测试结果如图:

已经修改的差不多了,下一步就是做成jar,以供本项目使用。步骤很简单。右键项目,选择“导出”→“Java”→“jar文件”,下一步,把右侧的勾全去掉,然后设定一下jar的生成路径,点击“完成”即可。javadoc生成方式差不多,可以参考这里。

手痒了么?快来试试看吧。当然,现在做的myrsslib4j 跟rsslib4j一样,仅仅支持rss格式的博客。下篇博客给大家奉献修改过的rome——myrome,它很好的支持了rss和atom 2种格式的博客。此阅读器会以myrome来解析在线的订阅信息,敬请期待吧。

加句题外话,为了更好的与大家分享,我在Google Code中上传了myrsslib4j的源代码。项目主页:https://code.google.com/p/myrsslib4j/ 。个人能力所限,难免会有瑕疵,欢迎大家多多指正。

Web版RSS阅读器(四)——定制自己的Rss解析库myrsslib4j相关推荐

  1. rss阅读器保存html文件,轻量级RSS阅读器网页版:selfoss安装教程

    说明:关于RSS阅读器,我们知道的有Feedbin.FreshRSS等,功能都挺强大的,这里就再介绍个轻量级的RSS阅读器selfoss,使用起来是非常简单的,界面颜值也还不错,支持很多种订阅和网站, ...

  2. 用JSP实现基于Web的RSS阅读器

    2019独角兽企业重金招聘Python工程师标准>>> 一 RSS介绍 根据维基百科(http://zh.wikipedia.org/wiki/RSS)的定义,"RSS是一 ...

  3. 推荐RSS阅读器NewsGator

    一.什么是RSS? 也许大家是第一次听到RSS这个概念,那什么是RSS呢?RSS是站点用来和其他站点之间共享内容的一种简易方式(也叫聚合内容),通常被用于新闻和其他按顺序排列的网站,例如Blog. 一 ...

  4. 阅读器之家推荐几款比较好用的rss阅读器

    那个rss阅读器好? 阅读器之家推荐几款比较好用的rss阅读器,下面我们就来对比一下最近名气比较大的四款RSS阅读器,看看哪一款功能更强大,更适合我们使用. rss阅读器是什么? RSS阅读器是一种软 ...

  5. 常用的RSS阅读器评测

    本文是一个知识普及文章,主要讲述RSS阅读器的主要作用和常见用途,如果你已经熟悉了解RSS阅读器,请忽略本文,如果你一直使用浏览器阅读信息,那么请尝试一下RSS阅读器,你可以看到自己的阅读习惯可能会或 ...

  6. Web版RSS阅读器(三)——解析在线Rss订阅

    上篇博客<Web版RSS阅读器(二)--使用dTree树形加载rss订阅分组列表>已经写到读取rss订阅列表了,今天就说一下,当获取一条在线rss订阅的信息,怎么去解析它,从而获取文章或资 ...

  7. ino查看工具android版,(组图)老牌 RSS 阅读器 Inoreader 安卓版 UI 改版了

    软餐(ruancan.com)获悉,老牌的 RSS 阅读器 Inoreader 近日向 Android 平台推出了 Inoreader 7.0 Beta 版,在该版本上,Inoreader 对 UI ...

  8. rss阅读器保存html文件,4款在线RSS阅读器使用体验

    RSS阅读有以下优点:您可以看到没有广告和图片的标题或文章的概要阅读,这样你不必阅读全文即可知文章讲的一个意思是什么,为您节省时间. RSS阅读器会自动更新你定制的网站内容,保持新闻的及时性.要订阅新 ...

  9. RSS阅读器简单介绍

    这篇不是编程技术文章. 预计网站的初期推广将会较多的使用RSS,又由于现在RSS阅读器的普及率不高,而我也有朋友只听说RSS阅读器好却不清楚怎么使用的,所以就写这个了. 关于RSS的定义,需要看这篇文 ...

最新文章

  1. 关于ArrayList的几大问题,看完还不懂来打我!
  2. 报名 | IBM苏中:从深蓝到AlphaGo,从大数据到认知商业
  3. 如何解决“HttpException (0x80004005): 超过了最大请求长度”问题
  4. ARM 之六 Cortex-M 内核中断/异常系统、中断优先级/嵌套 详解
  5. boost::mpl模块实现if相关的测试程序
  6. const对象,NULL和nullptr,C++中创建对象数组
  7. update yum 到指定版本_centos使用yum update升级到指定小版本
  8. java学生签到系统视频教程_手把手教你做一个Java web学生信息、选课、签到考勤、成绩管理系统附带完整源码及视频开发教程...
  9. 设计灵感|耐人寻味的中文字体海报
  10. (2) OpenSSL命令
  11. WINX的消息分派机制(续)
  12. 搭建mqtt服务器apollo
  13. FFmpeg入门详解之71:获取ffmpeg转码的实时进度
  14. python语言转换为go_从 Python 到 Golang-Go语言中文社区
  15. 【考前冲刺】计算机三级网络技术之应用题-路由汇聚与子网划分
  16. Debezium系列之:使用Debezium接入PostgreSQL数据库数据到Kafka集群的详细技术文档
  17. 计算机主机光驱弹不出来怎么办,电脑dvd光驱打不开,光驱弹不出来解决
  18. 一分钟教你查询并设置极兔快递物流状态
  19. css-两种画弧线方法
  20. 【原创】Quartus II 简单设计流程

热门文章

  1. hadoop1.1.2分布式安装---集群动态增减节点
  2. JAVA之旅(二十八)——File概述,创建,删除,判断文件存在,创建文件夹,判断是否为文件/文件夹,获取信息,文件列表,文件过滤
  3. 拯救动画卡顿之FLIP
  4. 【活着活着就老了-冯唐】阅后
  5. tar分卷压缩/解压大文件
  6. CMOS图像传感器的曝光及读取时序
  7. 智联招聘的用户要注意了,这个问题可是关系到工作的机会的
  8. 吴恩达机器学习笔记week8——神经网络 Neutral network
  9. 自然语言处理NLP之信息检索
  10. 坛经与禅宗的智慧-王德峰