`

java实现带HTML代码的文章摘要截取

 
阅读更多

知大家是否已经注意到个人知客首页和列表页的文章已经实现了部分摘要内容的显示呢?这个看似简单的功能其实给我添了不少麻烦的说,前几天终于解决了,现在和大家一起分享一下经验,嘿嘿~~

普通的纯文本文字截取,大家想必已经很熟悉了,

java.lang.String.String(byte[] arg0, int arg1, int arg2)

就可以了,jsp里substring也能解决,但是加了HTML代码进去,想截取出一篇文章的部分内容就不那么容易,截取很容易就破坏了HTML代码的完整性,其后果甚至会影响你的整个页面的布局(我测试时候知客的页面就全飞了,恐怖ing)。

也考虑过将文章里的所有HTML语言全部过滤掉,这个曾经用在做SEO优化时META的Description内容,

replaceAll("<[.[^<]]*>","").replaceAll("[\\n|\\r]","")

就可以办到了,正则表达式<[.[^<]]*>可以粗略的过滤掉大部分的HTML标签,无疑这样做也可以达到摘要的目的,但是用户体验(UE)就差了很多了,大家肯定不愿意自己的图片,表格就这么从自己的首页里消失吧。

那么只有去分析文章的HTML标签了,把所有成对的标签都摘出来,以标签为单位去截取?或者截取后,对缺失的HTML标签进行补足,不管怎么样,这样的工作量和复杂度都是目前难以接受的(我得做一个准HTML代码语法分析器,汗~),时间不允许啊。。。

最后无意中发现一个强大的API HTML Parser,这是一个在 SourceForge.net 上比较活跃的项目之一,目前的最新版本是 1.4 发行版。有如 HTML Parser 网站的自我介绍: HTML Parser 是一个对现有的 HTML 进行分析的快速实时的解析器,事实上在应用过程中你更为惊叹于 HTML Parser 给你带来一些周到的处理。

下面是相关的资料和做法:

HTML Parser项目主要可以用在以下两个方面:

1. 信息提取

  • 文本信息抽取,例如对HTML进行有效信息搜索
  • 链接提取,用于自动给页面的链接文本加上链接的标签
  • 资源提取,例如对一些图片、声音的资源的处理
  • 链接检查,用于检查HTML中的链接是否有效
  • 页面内容的监控

2. 信息转换

  • 链接重写,用于修改页面中的所有超链接
  • 网页内容拷贝,用于将网页内容保存到本地
  • 内容检验,可以用来过滤网页上一些令人不愉快的字词
  • HTML信息清洗,把本来乱七八糟的HTML信息格式化
  • 转成XML格式数据

HTML Parser并没有对以上提到的一些应用进行专门的处理,但是它完全可以胜任上面提及的功能,在实际应用中如果遇见上面提及的问题可以使用该项目来处理。

解决问题
接下来我主要针对我们在前面提过那个网页截断的问题进行处理。我的做法是强行对HTML内容进行截断,然后把截断后的内容传递给HTML Parser,由它来补全缺漏的标签。这样做可能有些内容显示不全,但是至少不会破坏页面的排版。通过这样一个简单的例子可以了解HTML Parser的基本结构以及使用流程。

首先从SourceForge网站上下载HTML Parser的压缩包(下载网址参照文章最后的资料参考部分),下图是解压后的目录结构,其中画红线的是我们所需要的jar包文件。把这个文件加到项目的类路径中,其他类可以不管!



    
        /** 
 * 获取HTML的预览信息,其中content是对象的一个属性,也就是待处理的HTML内容
 * @return  
*/

 public String getPreviewContent(){
 
        //截取前N个字符
 String ct = StringUtils.left(content,MAX_COUNT);
 
        //对一些未完成的标签先补齐,避免出现例如<tab这样的标签
 if(ct!=null&&content!=null) {
  int idx2 = ct.lastIndexOf('>'); 
  int idx1 = ct.lastIndexOf('<'); 
  if((idx2==-1 && idx1>=0) || idx1 > idx2) { 
   String ct2 = content.substring(ct.length());
   int idx3 = ct2.indexOf('>'); 
   if(idx3!=-1 && idx3<(MAX_COUNT2-MAX_COUNT)) { 
    ct += content.substring(ct.length(),ct.length()+idx3+1);
   }  
  } 
 } 
 
        //对于一些页面嵌入了ActiveX对象进行预处理
 if(ct!=null&&content!=null) {  
  int idx2 = ct.toLowerCase().lastIndexOf("</object>"); 
  int idx1 = ct.toLowerCase().lastIndexOf("<object"); 
  if((idx2==-1 && idx1>=0) || idx1 > idx2) {
   String ct2 = content.substring(ct.length()).toLowerCase(); 
   int idx3 = ct2.indexOf("</object>"); 
   if(idx3!=-1) 
    ct += content.substring(ct.length(),ct.length()+idx3+9);
   else   
    ct = ct.substring(0,idx1); 
   }
  }
  if(ct!=null&&content!=null) {
   Parser parser = Parser.createParser(new String(ct.getBytes(),ISO8859_1));
   
        //中文信息必须转码后方可传入
    
        Node [] tables = parser.extractAllNodesThatAre (TableTag.class);
   if(tables!=null&&tables.lengtd>0) { 
    TableTag tableTag = (TableTag)tables[0]; 
    ct = ct.substring(0,tableTag.getStartPosition()) 
    + new String(tableTag.toHtml().getBytes(ISO8859_1));
    
        //处理后的数据转回GBK的编码 
   } 
  } 
 return ct;
}

      

上面这段代码就是用于显示HTML概要信息的方法,其中粗体部分是使用HTML Parser进行处理的过程。类Parser是HTML Parser的入口,我们可以将HTML文本信息传入给它,或者可以直接传递一个URL地址,如下:


Parser parser = new Parser("http://www.javayou.com");

初始化一个Parser实例后,紧接着就是对所传入的HTML内容进行解析,大家注意红色粗体的那行代码,从方法名我们很容易理解,该方法就是将HTML内容中存在的所有的表格给解析出来放到一个数组去,该方法所需的参数就是节点的类型,我们这里用的是表格的标签,几乎HTML的标签中都有对应的一个对应的类,比如FormTag、InputTag、AppletTag等等,这些标签类都在org.htmlparser.tags包中。根据我们要处理不同的标签传入不同的类,这种做法使我们可以很方便的处理其他类型的标签。返回的数组中每个元素都是你传入类的一个实例,通过这个实例可以访问到当前这个标签的起始未知、结束标签的未知以及包含在标签中的文本信息,同时也可以访问其父标签以及所有的子标签等等,同时我们可以通过toHtml方法来对标签中包含的HTML信息进行清洗,HTML Parser会自动帮我们把一些没有关闭的标签加上,这样所生成的字符串中就包含着完整的格式控制信息,在页面上显示这样的信息也不会破坏版面布局,达到了我预期的效果。

为了使大家更直观的看到执行效果,我们再来一个小例子并附上执行的结果:


public static void main(String[] args) throws Exception { 
 //不完整格式的HTML信息
 String html = "我们是害虫<table>1234567890<table>lk你好中国"; 
 Parser parser = Parser.createParser(new String(html.getBytes(),"8859_1")); 
 Node [] tables = parser.extractAllNodesThatAre (TableTag.class); 
 for (int i = 0; i < tables.length; i++)    {
  TableTag tableTag = (TableTag)tables[i]; 
  //打印出结束标签所在的未知       
  System.out.println("END POS:"+tableTag.getEndTag().getEndPosition());  
  //补齐未结束的标签并打印   
  System.out.println(new String(tableTag.toHtml().getBytes("8859_1")));  
 }    
}

这段代码旨在找出一段不完整 HTML 信息中的所有表格标签,然后打印出经过格式化后的 HTML 信息,下图是在 Eclipse 环境下的执行结果。


为了更好的在实际的业务中应用HTML Parser 项目,HTML Parser 还提供了几个例子用于处理前面我们提到的功能实现。这些例子在解压目录下的 bin 都有批处理命令可以执行,执行时给命令传入 URL 地址或者是 html 文件的路径即可。

HTML Parser 项目仅仅是提供给我们一个简单而强健的 API 用于分析 HTML 文本信息,更多的应用模式还有待于我们自己去发掘,希望本文能将你引入 HTML Parser 的大门


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics