html分析器——jericho-html-3.3分解table

原部分来自Internet上的其他博客,只是因为很长一段时间。忘了谁是参考,这里说声抱歉。。

先贴一些html页:

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=GBK">
<title>HTML Parser</title>
<meta name="generator" content="Namo WebEditor">
</head>
<body>
<table width=620 border=0 cellpadding=1 cellspacing=0 bgcolor=#0066cc>
	<tr>
		<td width=100%>
		<table width=100% border=0 cellpadding=4 cellspacing=0 bgcolor=#D3E5FB>
			<tr bgcolor=#D3E5FB>
				<td width=20%><font size="2" face="Arial,Verdana"><b>想学习
				Name</b></font><br>
				</td>
				<td width=13%><font size="2" face="Arial,Verdana"><b>Result</b></font><br>
				</td>
				<td width=8%><font size="2" face="Arial,Verdana"><b>Time</b></font><br>
				</td>
				<td width=59%><font size="2" face="Arial,Verdana"><b>Synopsis</b></font><br>
				</td>
			</tr>
			<tr bgcolor=#eeeeee>
				<td width=20%><font size="1" face="Arial,Verdana"><b>9</b>
				想学习</font><br>
				</td>
				<td width=13%><font size="1" face="Arial,Verdana"><font
					color=#ff0033>+FAIL</font> <a
					href="v4_wireless_802.1x_full/cdrouter_dhcp_20.txt">想学习</a></font><br>
				</td>
				<td width=8%><font size="1" face="Arial,Verdana">12:31</font><br>
				</td>
				<td width=59%><font size="1" face="Arial,Verdana">想学习</font><br>
				</td>
			</tr>
			<tr bgcolor=#ffffff>
				<td width=20%><font size="1" face="Arial,Verdana"><b>1</b>
				cdrouter_basic_1</font><br>
				</td>
				<td width=13%><font size="1" face="Arial,Verdana">Pass <a
					href="v4_wireless_802.1x_full/cdrouter_basic_1.txt">想学习</a></font><br>
				</td>
				<td width=8%><font size="1" face="Arial,Verdana">00:00</font><br>
				</td>
				<td width=59%><font size="1" face="Arial,Verdana">想学习</font><br>
				</td>
			</tr>
		</table>
		</td>
	</tr>
</table>
</body>
</html>

对于这个页面来说我想取出全部的td里面的文字内容,该怎么办呢。假设用正則表達式,我还真是难以写出正确的,来解析出我所要的结果。

在网上搜索了一下jericho-html-3.3这个插件,用来解析table。的确非常方便。

代码例如以下:

package com.xxx.hbuassys.test;

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

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;

public class HtmlParser
{
    public static void main(String[] args) throws Exception
    {
        String sourceUrlString="test.html";

        if(sourceUrlString.indexOf(':') == -1)
            sourceUrlString ="file:"+sourceUrlString;
        Source source=new Source(new URL(sourceUrlString));
        List Elements_TABLE=source.getAllElements(HTMLElementName.TABLE);
        Elements_TABLE.remove(0);//因为table相互嵌套。我们须要的是第二个,所以删掉第一个
        Iterator it_TABLE = Elements_TABLE.iterator();
        while(it_TABLE.hasNext())
        {
            Element Element_TABLE = (Element)it_TABLE.next();
//        	System.out.println("**"+Element_TABLE.toString()+"\n**");
            Segment getContent_TABLE = (Segment)Element_TABLE.getContent();
            List Elements_TR = getContent_TABLE.getAllElements(HTMLElementName.TR);
            Iterator it_TR = Elements_TR.iterator();
            while(it_TR.hasNext())
            {
                Element Element_TR = (Element)it_TR.next();
                Segment getContent_TR = (Segment)Element_TR.getContent();
                List Elements_FONT = getContent_TR.getAllElements(HTMLElementName.FONT);
                Iterator it_FONT = Elements_FONT.iterator();
                int i = 1;
                while(it_FONT.hasNext())
                {
                    Element Element_FONT = (Element)it_FONT.next();
                    Segment getContent_FONT = (Segment)Element_FONT.getContent();
                    String a1 = getContent_FONT.toString();
                    System.out.println(i + " = " + Element_FONT.getContent().getTextExtractor().toString());
                    i++;
                }
                System.out.println();
            }
        }
    }
}

结果:

1 = 想学习 Name

2 = Result

3 = Time

4 = Synopsis

1 = 9 想学习

2 = +FAIL 想学习

3 = +FAIL

4 = 12:31

5 = 想学习

1 = 1 cdrouter_basic_1

2 = Pass 想学习

3 = 00:00

4 = 想学习

大致的思路就是,先取出全部的table标签,然后对须要的table进行解析,取出里面的tr,在从tr里面取出td这样就能够得到我们须要的内容了。

假设仅仅讲到这,那么就跟网上其它人讲的没有什么差别了。

由于项目的须要,使用此插件发现了一个问题:

假设html页面的编码是UTF-8的格式,那么解析出来的内容就会是乱码。假设直接对这些乱码编码。採用new String(str.getBytes(),"GBK");等之类的操作都不能解决这个问题。本人亲自測试过。

比如html页面变为:

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<title>HTML Parser</title>
<meta name="generator" content="Namo WebEditor">
</head>
<body>
<table width=620 border=0 cellpadding=1 cellspacing=0 bgcolor=#0066cc>
	<tr>
		<td width=100%>
		<table width=100% border=0 cellpadding=4 cellspacing=0 bgcolor=#D3E5FB>
			<tr bgcolor=#D3E5FB>
				<td width=20%><font size="2" face="Arial,Verdana"><b>想学习
				Name</b></font><br>
				</td>
				<td width=13%><font size="2" face="Arial,Verdana"><b>Result</b></font><br>
				</td>
				<td width=8%><font size="2" face="Arial,Verdana"><b>Time</b></font><br>
				</td>
				<td width=59%><font size="2" face="Arial,Verdana"><b>Synopsis</b></font><br>
				</td>
			</tr>
			<tr bgcolor=#eeeeee>
				<td width=20%><font size="1" face="Arial,Verdana"><b>9</b>
				想学习</font><br>
				</td>
				<td width=13%><font size="1" face="Arial,Verdana"><font
					color=#ff0033>+FAIL</font> <a
					href="v4_wireless_802.1x_full/cdrouter_dhcp_20.txt">想学习</a></font><br>
				</td>
				<td width=8%><font size="1" face="Arial,Verdana">12:31</font><br>
				</td>
				<td width=59%><font size="1" face="Arial,Verdana">想学习</font><br>
				</td>
			</tr>
			<tr bgcolor=#ffffff>
				<td width=20%><font size="1" face="Arial,Verdana"><b>1</b>
				cdrouter_basic_1</font><br>
				</td>
				<td width=13%><font size="1" face="Arial,Verdana">Pass <a
					href="v4_wireless_802.1x_full/cdrouter_basic_1.txt">想学习</a></font><br>
				</td>
				<td width=8%><font size="1" face="Arial,Verdana">00:00</font><br>
				</td>
				<td width=59%><font size="1" face="Arial,Verdana">想学习</font><br>
				</td>
			</tr>
		</table>
		</td>
	</tr>
</table>
</body>
</html>

得到的结果是:

1 = ???

? Name

2 = Result

3 = Time

4 = Synopsis

1 = 9 ???

?

2 = +FAIL ?

???

3 = +FAIL

4 = 12:31

5 = ?

?

??

1 = 1 cdrouter_basic_1

2 = Pass ??

??

3 = 00:00

4 = ?

?

??

採用的方法是:改变<meta http-equiv="content-type" content="text/html;charset=UTF-8">变为:<meta http-equiv="content-type" content="text/html;charset=GBK">

具体情况,參考代码例如以下:

package com.xxx.hbuassys.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.Source;

public class HtmlParser
{
    public static void main(String[] args) throws Exception
    {
    	BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(new File("test.html"))));
//    	BufferedReader reader=new BufferedReader(new FileReader(new File("test.html")));
    	StringBuilder sbf=new StringBuilder();
    	String str=null;
    	while((str=reader.readLine())!=null){
    		sbf.append(str).append("\n");
    	}
    	//解决中文乱码的方法
    	String html=sbf.toString().replace("<meta http-equiv=\"content-type\" content=\"text/html;charset=UTF-8\">", "<meta http-equiv=\"content-type\" content=\"text/html;charset=GBK\">");
//    	System.out.println(html);
        Source source=new Source(html);
        List Elements_TABLE=source.getAllElements(HTMLElementName.TABLE);
        Elements_TABLE.remove(0);//因为table相互嵌套,我们须要的是第二个,所以删掉第一个
        Iterator it_TABLE = Elements_TABLE.iterator();
        while(it_TABLE.hasNext())
        {
            Element Element_TABLE = (Element)it_TABLE.next();
//        	System.out.println("**"+Element_TABLE.toString()+"\n**");
            Segment getContent_TABLE = (Segment)Element_TABLE.getContent();
            List Elements_TR = getContent_TABLE.getAllElements(HTMLElementName.TR);
            Iterator it_TR = Elements_TR.iterator();
            while(it_TR.hasNext())
            {
                Element Element_TR = (Element)it_TR.next();
                Segment getContent_TR = (Segment)Element_TR.getContent();
                List Elements_FONT = getContent_TR.getAllElements(HTMLElementName.FONT);
                Iterator it_FONT = Elements_FONT.iterator();
                int i = 1;
                while(it_FONT.hasNext())
                {
                    Element Element_FONT = (Element)it_FONT.next();
                    Segment getContent_FONT = (Segment)Element_FONT.getContent();
                    String a1 = getContent_FONT.toString();
                    System.out.println(i + " = " + Element_FONT.getContent().getTextExtractor().toString());
                    i++;
                }
                System.out.println();
            }
        }
    }
}

结果例如以下:

1 = 想学习 Name

2 = Result

3 = Time

4 = Synopsis

1 = 9 想学习

2 = +FAIL 想学习

3 = +FAIL

4 = 12:31

5 = 想学习

1 = 1 cdrouter_basic_1

2 = Pass 想学习

3 = 00:00

4 = 想学习

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-12 19:26:28

html分析器——jericho-html-3.3分解table的相关文章

全文索引--自定义chinese_lexer词典

本文来详解一下如何自定义chinese_lexer此法分析器的词典 初始化数据 create table test2 (str1 varchar2(2000),str2varchar2(2000)) ; insert into test2 values('地质图','中国和反馈砀山龙卷风流口水地质图') ; insert into test2 values('图片','图') ; commit ; 创建此法分析器并且创建全文索引(注意词典只对chinese_lexer起作用) exec ctx_

DBO权限日志备份专用一句话木马 - 寒龙网出品 以前的博客站因为程序错乱改为反病毒联盟后 本博客基于博客园地 感谢关注

备分专用一句话 加个response.end会有不一样的效果,也就是插入一句话后所有的代码都无效,在一句话这里打止,也就减小了webshell的大小. 日志备分WEBSHELL标准的七步: 1.InjectionURL';alter database XXX set RECOVERY FULL-- (把sql设置成日志完全恢复模式) 2.InjectionURL';create table cmd (a image)-- (新建立一个cmd表) 3.InjectionURL';backup lo

如何使用《DB 查询分析器》高效地生成旬报货运量数据

如何使用<DB 查询分析器>高效地生成旬报货运量数据 马根峰                    (广东联合电子服务股份有限公司, 广州 510300) 1      引言   中国本土程序员马根峰(CSDN专访马根峰:海量数据处理与分析大师的中国本土程序员)推出的个人作品----万能数据库查询分析器,中文版本<DB 查询分析器>.英文版本<DB Query Analyzer>.它具有强大的功能.友好的操作界面.良好的操作性.跨越各种数据库平台乃至于EXCEL和文本文

selenium 如何处理table

qi_ling2005  http://jarvi.iteye.com/blog/1477837 andyguo  http://blog.csdn.net/gzh0222/article/details/7568490 以前在selenium RC 里面有一个getTable方法,是得到一个单元格中的文本.其详细描述如下: Java代码   /** Gets the text from a cell of a table. The cellAddress syntax <span style=

基于Table方法降低代码圈复杂度

描述: 在项目开发过程中,经常要求圈复杂度不能超过10,有时候写着写着圈复杂度就很大,我在项目代码中见过函数圈复杂度大于100的函数,由于历史的原因,代码越积越多,没人出去重构,导致后面很难懂和维护,所以在编码初期就应该在心中有个要求,就是圈复杂度不能超过10,如果超过10,肯定是代码逻辑写的过于复杂,要回过头来 想想怎么去分解功能,让流程简单易懂. 本文主要通过一些例子来介绍基于Table方式降低圈复杂度的过程. 例子1:一个简单的游戏控制函数 你可能会遇到如下类似的代码: if(strcmp

LL(1)语法分析器 //c++实现

#include<iostream> #include<string> #include<map> #include<vector> #include<stack> #include<set> #include<cstring> using namespace std; map<char,int>getnum; char getchar[100]; //获得对应字符 vector<string>pr

小酌重构系列[4]&mdash;&mdash;分解方法

概述 "分解方法"的思想和前面讲到的"提取方法"."提取方法对象"基本一致.它是将较大个体的方法不断的拆分,让每个"方法"做单一的事情,从而提高每个方法的可读性和可维护性.分解方法可以看做是"提取方法"的递归版本,它是对方法反复提炼的一种重构策略. 分解方法 下图表示了这个重构策略,第1次提炼和第2次提炼都采用了"提取方法"这个策略. 何时分解方法? "分解方法"最终

selenium 获取table数据

public class Table { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub WebDriver driver = ExplorerBase.IESetting(); String url = "http://zs.njust.edu.cn/newzs/news/zhxw/20140710151805.htm"; driver.m

《万能数据库查询分析器》实现使用SQL语句直接高效地访问文本文件

<万能数据库查询分析器>实现使用SQL语句直接高效地访问文本文件 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要    用SQL语句来直接访问文本文件?是在做梦吗? 本文详细地介绍了"万能数据库查询分析器",中文版本<DB 查询分析器>.英文版本<DB Query Analyzer>在 文本文件处理方面非常强大的功能,你可以直接用SQL语句来访问这些文本文件,访问250万条记录的文件的复杂的关联操作,也不过用时59秒钟.需要注意