`

从HTML中攫取你所需的信息

阅读更多
本文并非想通过分析HTML的语法然后从中解析出数据,这样做实现困难而且没有什么实际应用的意义,或者应该这样说:我们并不想 自己去实现一个HTML语法的分析器。我们要做的仅仅是从HTML中提取我们所需的信息。不同于XML这种对格式要求非常严格的标志语言,HTML在推出 时并没有对其格式进行严格的定义,比如HTML中标签并不一定要成对出现,但是又要求浏览器能尽量的正确显示其所要表达出来的内容。浏览器经过多年发展其 适应能力越来越强,很多格式非常糟糕的HTML文件都能显示得令人满意。不过如果我们需要精确的获取HTML中包含的数据,这恐怕比显示一个HTML更令 人头疼。现在终于找到治疗头疼的特效药了!

接下来我们要介绍 的就是使用 JAVA 语言如何简单快速的攫取 HTML 中包含的数据。我们会借助一些现有的成熟 API 来完成这件事,因为如果仅仅是为了实现这个功能,完全没有必要自己去实现 HTML 的语法分析器。我们引入了一个开源的项目-- HTML Parser ,这是一个在 SourceForge.net 上比较活跃的项目之一,目前的最新版本是 1.4 发行版。有如 HTML Parser 网站的自我介绍: HTML Parser 是一个对现有的 HTML 进行分析的快速实时的解析器,事实上在应用过程中你更为惊叹于 HTML Parser 给你带来一些周到的处理。

考虑到很多读者并不清楚该项目的应用场合,因此我依照以前的步骤来组织这篇文章。首先是提出问题,讲述我在怎么一种情况下需要对 HTML 进行语法解析;其次是分析问题,如何考虑到使用 HTML Parser 来达到我所需要的目的;最后就是解决问题。

提出问题

在 实际开发一个内容管理项目时,由于内容是基于 HTML 的格式进行存储以及编写,并提供了一个基于浏览器的所见即所得的 HTML 编辑器。用户经常会直接从其他网站上复制一些带格式的内容后直接发布,首页会显示这些内容的概要信息,概要信息直接切割内容,从中读取前几个字。这种做法 引发的问题是,截断的内容包含不完整的格式信息,因为切割的长度是固定的,比如我取前 400 个字用于做概要显示,这时候经常把内容中的一些表格切断,这些包含不完整格式信息的内容带来的问题就是它将破坏整个页面的布局,我们碰到最常见的问题就是 页面被撑大,从输出的页面源码中可以看出就是因为这些不完整的表格标签导致。

 

分析问题

解 决我们前面提出的问题的办法唯有使内容的切割更加智能化,可以自动的处理例如表格被切断这个影响格式的罪魁祸首。之前的做法是在切割后的内容中搜索没有被 正常结束的表格标签,这解决了大部分内容无法正常显示的问题,但是这仅仅处理了最简单的情况,一旦出现嵌套表格被切割的情况也就无能为力,如果我们再自己 来处理嵌套表格的情况,那考虑的问题就非常的多,因为为了使页面的排版美观,网页设计师大量的使用表格来进行处理,事实上这也是编写 HTML 的唯一办法。因此你可能要对各种各样的表格嵌套方式进行单独的处理,想象一下你编写一个万行的代码来完成一个看似简单的问题,你的领导肯定跟你急了 ^_^,问题还在于你这一万行的代码并不一定可以解决问题。因此在这个问题的处理上我们要尽量采取一些成熟稳定的API,HTML Parser 就是一个用于解析 HTML 文本的开源项目,它可以准确高效的对HTML文本中的格式、数据进行处理,有将近二十位来自世界各地的工程师在为这个项目工作。

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 的大门。


参考资料

 

分享到:
评论

相关推荐

    jsoup攫取你所需的信息

    从HTML中攫取你所需的信息 和扩展HTMLParser 对自定义标签的处理能力。但现在我已经不再使用htmlparser 了,原因是htmlparser 很少更新,但最重要的是有了jsoup 。

    jsoup-1.7.1

    Java 程序在解析HTML 文档时,相信大家都接触过htmlparser 这个开源项目,我曾经在IBM DW 上发表过两篇关于htmlparser 的文章,分别是:从HTML中攫取你所需的信息 和扩展HTMLParser 对自定义标签的处理能力。...

    网络爬虫资源包及使用教程

    Java 程序在解析HTML 文档时,相信大家都接触过htmlparser 这个开源项目,我曾经在IBM DW 上发表过两篇关于htmlparser 的文章,分别是:从HTML中攫取你所需的信息 和扩展HTMLParser 对自定义标签的处理能力。...

    jsoup支持包_教程_源代码

    Java 程序在解析HTML 文档时,相信大家都接触过htmlparser 这个开源项目,我曾经在IBM DW 上发表过两篇关于htmlparser 的文章,分别是:从HTML中攫取你所需的信息 和扩展HTMLParser 对自定义标签的处理能力。...

    颜色代码查看器(实用攫取工具)

    比较好用的一个颜色代码攫取工具;无级调色功能;屏幕任意抓色功能(工具来自网络)

    挖掘小客户市场的价值 攫取超额利润.ppt

    挖掘小客户市场的价值 攫取超额利润.ppt

    计算机-爬虫-利用网络爬虫技术攫取他人数据的正当性认定:以典型案例为视角.pdf

    计算机-爬虫-利用网络爬虫技术攫取他人数据的正当性认定:以典型案例为视角.pdf

    密钥攫取人Product Key Explorer 2.9.5.0

    电脑内各种注册程序使用久了,密钥忘了咋办?用了它,一切好办。

    matlab源码离散Hopfield神经网络的联想记忆-数字识别.rar

    如何从这些残缺不全的字符中攫取完整的信息,是字符识别的关键问题。作为字符识别的组成部分之一的数字识别在邮政、交通及商业票据管理方面有着极高的应用价值。目前有很多种方法用于字符识别,主要分为神经网络识别...

    商业银行在大数据时代的发展策略_郑重.pdf

    在“大数据”时代,以互联网为代表的现代信息科技将 从根本上改变现代金融运营模式。数据海量化、多样化、传 ...中攫取价值,从数据中赢取未来,引领传统模式变革,用创 新的理念和行动主动拥抱“大数据”时代。

    图解网站分析 epub

    本书以图配文,结合实例详细讲解了如何利用从网站上获取的各种数据了解网站的运营状况,如何从数据中攫取最有用的信息,如何优化站点,创造更大的网站价值。本书适合各类网站运营人员阅读。

    网页关键词监控程序v3.0.1230是一款优秀批量多线程对指定网页监控.exe

    目前是信息爆炸的时代,我们已经没有太多的精力去用双眼攫取有用的信息,《网页关键词监控 程序》监控机器人将有用的信息自动发给自己,解放双眼,掌控先机。软件简介 《网页关键词监控程序》是一款优秀批量多线程对...

    对快速移动中的数据的分析和行动:复杂事件处理

    复杂事件处理技术 (CEP)提供了一种创新的方法,从实时的事件数据中攫取智慧。作为一个应用开发平台,它提供了高级工具来定义事件如何被处理和分析。作为一个事件驱动架构 (EDA)引擎,它提供了获取、聚合、关联与分析...

    大数据时代心得体会.doc

    因此,建设"数据仓库",培养"数据思维",养成"数据治理",创造"数据融合",实现 "数据应用"才能拥抱"大数据"时代,从数据中攫取价值,笑看风云变换,稳健赢取未来 。 ----------------------- 大数据时代心得体会...

    2服务器备份方案.doc

    概述 服务器备份是指针对于服务器所产生的数据信息进行相应的存储备份过程,从而保障 数据的安全运行,从狭义上来看信息的价值在于其潜在用途,并会随着时间的推移而改 变。数据管理和保护可攫取信息的最大价值,并...

    网络安全报告

    Internet的迅猛发展满足了人们对信息的渴求,然而Internet里也存在许多不安全因素,网络信息的非法攫取,网络体系的肆意破坏等等都将给企业带来难以估计的损失。因此,防火墙技术在企业网络安全防护中具有越来越重要...

    论文研究-控股股东的控制权私人收益:理论模型与经验证据.pdf

    选取2003--2006年间中国上市公司中发生的85笔大额且控制股东地位发生变更的非流通股转让交易为研究对象,通过实证研究表明: 中国上市公司中以大额股权转让溢价衡量的控股股东控制权私人收益规模平均达到10.66%;...

    闪电交易鲷鱼「Lightning Deal Snapper」-crx插件

    闪电交易攫取者可以帮助你赶上你想要的亚马逊闪电优惠,只要他们可用。有了这个扩展,即使你不在计算机上,你也可以尽快地选择你的闪电交易。 当你选择的交易即将到来的时候,你是否曾经陷入分心?不再。你可以专注...

Global site tag (gtag.js) - Google Analytics