`
tianhewulei
  • 浏览: 24493 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

nekohtml 帮助类

阅读更多
下面是一个nodehelper帮助类,主要是为了输出node 或者nodelist下的文字内容或者完整的html代码。
package com.isa.bbs.parser.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import javax.xml.transform.TransformerException;

import org.apache.xpath.XPathAPI;
import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.isa.bbs.parser.common.Block;
import com.isa.bbs.spider.common.SpiderGlobal;


public class NodeHelper {

	public static final int FIND_SUB = 0; // 找子节点
	public static final int FIND_SIB = 1; // 找同级节点
	public static final int FIND_END = 2; // 结束
	
	public static final String SEPARTOR = System.getProperty ("line.separator");
	
	/**
	 * 得到该nodelist下的所有文章内容。
	 * @param list
	 * @param sb
	 */
	public static String getNodeListPlainText(NodeList list){
		StringBuffer sb = new StringBuffer("");
		printNodeList(list, sb, 1);
		return sb.toString();
	}
	
	/**
	 * 获得该节点下指定的xpath匹配到的node节点
	 * @param node
	 * @param sequence
	 * @return
	 */
	public static NodeList getAllTargetNodeList(Node node, String sequence){
		if(node == null){
			return null;
		}		
		NodeList nodelist = null;
		try {
			nodelist = XPathAPI.selectNodeList(node, sequence);
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return nodelist;
	}
	
	/**
	 * 获得该nodelist下所有的文字内容,去掉A 和 style标签下的内容
	 * @param list
	 * @return
	 */
	public static String getNodeListPlainTextExceptTags(NodeList list){
		StringBuffer sb = new StringBuffer("");
		printNodeList(list, sb, 0);
		return sb.toString();
	}
	
	/**
	 * 得到该nodelist下的html代码。
	 * @param list
	 * @return
	 */
	public static String getNodeListHTML(NodeList list){
		StringBuffer sb = new StringBuffer("");
		printNodeListHTML(list, sb);
		return sb.toString();
	}
	
	/**
	 * 得到该node下的html内容
	 * @param node
	 * @param sb
	 */
	public static String getNodeHTML(Node node){
		StringBuffer sb = new StringBuffer("");
		printNodeHTML(node, sb);
		return sb.toString();
	}
	
	/**
	 * 获得该node下的文字内容,包括A 或者 style标签下的内容
	 * @param node
	 * @return
	 */	
	public static String getNodePlainText(Node node){
		StringBuffer sb = new StringBuffer("");
		printNodeValue(node, sb, 1);
		return sb.toString();
	}
	
	/**
	 * 获得该node下的文字内容,不包括A 或者 style标签下的内容
	 * @param node
	 * @return
	 */
	public static String getNodePlainTextExceptTags(Node node){
		StringBuffer sb = new StringBuffer("");
		printNodeValue(node, sb, 0);
		return sb.toString();
	}
	
	/**
	 * 得到nodelist中的文本
	 * @param list
	 * @param sb
	 * @param flag 0 除去A 或者 style 标签里面的字符串 1 保持原样
	 */
	private static void printNodeList(NodeList list, StringBuffer sb, int flag){
		if(list == null){
			return;
		}
		for (int i = 0; i < list.getLength(); i++) {
			Node node = list.item(i);
			if(flag == 0){
				if(node.getNodeName().equals("A") || node.getNodeName().equals("STYLE") ){
					continue;
				}
			}
			if (node.hasChildNodes()) { // 如果该节点含有子节点,表明它是一个Element。
				printNodeList(node.getChildNodes(), sb, flag); // 递归调用,操作该Element的子节点。
			} else if (node.getNodeType() == Node.TEXT_NODE) { // 检查这个非Element节点是否是文本
				String text =  node.getNodeValue().trim();
				if(!text.startsWith("<!--")){
					sb.append(text);
				}
			} else {
				continue;
			}
		}
	}

	/**
	 * 得到该节点的完整html表现形式
	 * @param node
	 * @param sb
	 */
	private static void printNodeHTML(Node node, StringBuffer sb){
		if(node == null){
			return ;
		}
		if(node.hasChildNodes()){
			sb.append("<"+node.getNodeName());
			NamedNodeMap attrs = node.getAttributes();
			for(int j=0;j<attrs.getLength();j++){
				sb.append(" "+attrs.item(j).getNodeName()+"=\""+attrs.item(j).getNodeValue()+"\"");
			}
			sb.append(">");
			for(int i=0;i<node.getChildNodes().getLength();i++){
				printNodeHTML(node.getChildNodes().item(i), sb);
			}							
			sb.append("</"+node.getNodeName()+">");
		}else if(node.getNodeType() == Node.TEXT_NODE){
			sb.append(node.getNodeValue());
		}else if(node.getNodeType() == Node.ELEMENT_NODE){
			sb.append("<"+node.getNodeName());
			NamedNodeMap attrs = node.getAttributes();
			for(int j=0;j<attrs.getLength();j++){
				sb.append(" "+attrs.item(j).getNodeName()+"=\""+attrs.item(j).getNodeValue()+"\"");
			}
			sb.append(">");				
			sb.append("</"+node.getNodeName()+">");
		}
	}
			
	/**
	 * 
	 * @param node
	 * @param sb
	 * @param flag 0 表示除去A、STYLE标签 1 表示留下A、STYLE标签
	 */
	private static void printNodeValue(Node node, StringBuffer sb, int flag){
		if(node == null){
			return;
		}
		if(node.hasChildNodes()){
			if(flag == 0){
				for(int i=0;i<node.getChildNodes().getLength();i++){
					if(node.getNodeName().equals("A") || node.getNodeName().equals("STYLE")){
						continue;
					}
					printNodeValue(node.getChildNodes().item(i), sb, flag);
				}
			}else{
				for(int i=0;i<node.getChildNodes().getLength();i++){
					printNodeValue(node.getChildNodes().item(i), sb, flag);
				}
			}
		}else if(node.getNodeType() == Node.TEXT_NODE){
			String text =  node.getNodeValue().trim();
			if(!text.startsWith("<!--")){
				sb.append(text);
			}			
		}
	}
		
	/**
	 * 得到该nodelist的完整的html内容
	 * @param list
	 * @param sb
	 */
	private static void printNodeListHTML(NodeList list, StringBuffer sb){
		if(list == null){
			return;
		}
		for (int i = 0; i < list.getLength(); i++) {
			Node node = list.item(i);
			if (node.hasChildNodes()) { // 如果该节点含有子节点,表明它是一个Element。
				sb.append("<"+node.getNodeName());
				NamedNodeMap attrs = node.getAttributes();
				for(int j=0;j<attrs.getLength();j++){
					sb.append(" "+attrs.item(j).getNodeName()+"=\""+attrs.item(j).getNodeValue()+"\"");
				}
				sb.append(">");
				printNodeListHTML(node.getChildNodes(), sb);	// 递归调用,操作该Element的子节点。			
				sb.append("</"+node.getNodeName()+">");
			}  else if(node.getNodeType() == Node.TEXT_NODE){	//如果该节点类型是一个文本类型的节点.
				sb.append(node.getNodeValue());
			} else if(node.getNodeType() == Node.ELEMENT_NODE){
				sb.append("<"+node.getNodeName());
				NamedNodeMap attrs = node.getAttributes();
				for(int j=0;j<attrs.getLength();j++){
					sb.append(" "+attrs.item(j).getNodeName()+"=\""+attrs.item(j).getNodeValue()+"\"");
				}
				sb.append(">");				
				sb.append("</"+node.getNodeName()+">");
			}
		}
	}	
	
	/**
	 * 查找给定的文件中是否含有特定的唯一性标志块。如果有,返回一个不为null的节点集合。
	 * @param block
	 * @param fileName
	 * @return
	 */
	public static NodeList getTargetNodeList(Block block, String fileName){
		DOMParser parser = null;
		NodeList list = null;
		try {
			String charset = SpiderGlobal.PAGE_ENCODING;
			parser = new DOMParser();
			parser.setProperty(
					"http://cyberneko.org/html/properties/default-encoding",
					charset);
			parser.setFeature("http://xml.org/sax/features/namespaces", false);
			File file = new File(fileName);
			BufferedReader in = new BufferedReader(new InputStreamReader(
					new FileInputStream(file)
					));
			parser.parse(new InputSource(in));
			in.close();
			Document doc = parser.getDocument();
			if(doc == null){
				return null;
			}
			list = XPathAPI.selectNodeList(doc, block.getBlockxpath());
		}  catch (Exception e){
			System.out.println("no filematch !" +e.getMessage());
			return null;
		}
		return list;
	}
}



以下是一个NekoHelper的帮助类,主要是根据传进来的文件的类型,是本地文件还是网络文件或者只是一段content内容,获得相应的DOMParser
package com.isa.bbs.parser.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.xml.transform.TransformerException;

import org.apache.xpath.XPathAPI;
import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.isa.bbs.parser.common.Block;
import com.isa.bbs.parser.common.Queue;
import com.isa.bbs.parser.common.SiteContext;
import com.isa.bbs.spider.common.SpiderGlobal;

public class NekoHelper {
		
	/**
	 * 通过给定的xpath、文件路径、是否是网络文件来获得符合该xpath路径下的节点集合
	 * @param block
	 * @param url
	 * @param isurl
	 * @return
	 */
	public static NodeList getTargetNodeList(Block block, String url , boolean isurl){
		if(block == null){
			return null;
		}
		DOMParser parser = getParser(url, isurl);
		Document doc = parser.getDocument();
		if(doc == null){
			return null;
		}
		NodeList list = null;
		try {			
			list = XPathAPI.selectNodeList(doc, block.getBlockxpath());
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
	
	public static Block getBlock(String blockname){
		Block block = null;
		if(Queue.siteQueue!=null) {
			SiteContext context = Queue.siteQueue.get(0);
			block = (Block)context.getAttribute(blockname);
		}		
		return block;
	}
	
	/**
	 * 给定xpath路径,在给定的content下获得指定的路径下的节点集合
	 * @param content
	 * @param xpath
	 * @return
	 */
	public static NodeList getContentByXpath(String content, String xpath){
		DOMParser parser = getStrParser(content);
		
		Document doc = parser.getDocument();
		if(doc == null){
			return null;
		}
		NodeList list = null;
		try{
			list = XPathAPI.selectNodeList(doc, xpath);
		}catch(TransformerException e){
			e.printStackTrace();
		}
		return list;
	}
	
	/**
	 * 获得指定的本地文件的解析器 DOMParser
	 * @param str
	 * @return
	 */
	private static DOMParser getStrParser(String str){
		DOMParser parser = null;
		try{
			parser = new DOMParser();
			parser.setProperty("http://cyberneko.org/html/properties/default-encoding",
					SpiderGlobal.PAGE_ENCODING);
			parser.setFeature("http://xml.org/sax/features/namespaces", false);			
			parser.parse(new InputSource(new StringReader(str)));
		}catch(Exception e){
			System.out.println("no filematch !" + e.getMessage());
		}
		return parser;
	}
	
	/**
	 * 获得指定的本地文件或者网络上指定的url下的解析器 DOMParser
	 * @param url
	 * @param isurl true 本地文件  false 网络文件
	 * @return
	 */
	public static DOMParser getParser(String url, boolean isurl){
		DOMParser parser = null;
		try{
			parser = new DOMParser();
			parser.setProperty("http://cyberneko.org/html/properties/default-encoding",
					SpiderGlobal.PAGE_ENCODING);
			parser.setFeature("http://xml.org/sax/features/namespaces", false);
			BufferedReader in = null;
			if(isurl){
				File file = new File(url);			
				in = new BufferedReader(new InputStreamReader(
						new FileInputStream(file),SpiderGlobal.PAGE_ENCODING));
			}else{
				HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection();
				conn.setRequestProperty("user-agent","mozilla/4.0 (compatible; msie 6.0; windows 2000)");
				conn.setConnectTimeout(30000); 
				conn.setReadTimeout(30000); 
				conn.connect();
				in = new BufferedReader(new InputStreamReader(
						conn.getInputStream(),SpiderGlobal.PAGE_ENCODING));
			}
			parser.parse(new InputSource(in));
			in.close();
		}catch(Exception e){
			System.out.println("no filematch !" + e.getMessage());
		}
		return parser;
	} 
			
	/**
	 * 得到该url下的文章内容
	 * @param url
	 * @return
	 */
	public static String getWebContent(String url) {
		String s = null;
		String src = url;
		String pageEncoding = SpiderGlobal.PAGE_ENCODING;
		try {
			// 从url打开stream
			InputStream in = null;
			HttpURLConnection conn = (HttpURLConnection)new URL(src).openConnection();
			conn.setRequestProperty("user-agent","mozilla/4.0 (compatible; msie 6.0; windows 2000)");
			conn.setConnectTimeout(30000); 
			conn.setReadTimeout(30000); 
			conn.connect();
			in = conn.getInputStream();
			// 开始读取内容正文。
			BufferedReader br = new BufferedReader(new InputStreamReader(in, pageEncoding));
			StringBuffer sb = new StringBuffer();
			char[] charBuf = new char[2048];
			int len = br.read(charBuf);
			while(len != -1) {
				sb.append(charBuf, 0, len);
				len = br.read(charBuf);
			}
			br.close();
			s = sb.toString();
		}catch(IOException ex) {
			System.err.println(src);
			System.out.println("Web页面读取失败!==IO异常");
			return null;
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println("Web页面读取失败!==普通异常");
			return null;
		}
		return s;
	}
	
}


分享到:
评论
1 楼 free0007 2012-03-29  

是高手写的代码!

相关推荐

    NekoHtml解析 html 文件

    博客链接中提到的是作者Tivonhou在iteye上的博客文章,虽然具体内容无法查看,但通常这类文章可能会涵盖如何使用NekoHtml解析HTML文件、解决常见问题、优化性能,以及与其他解析库对比等方面的知识。 在压缩包...

    nekohtml-1.9.13.zip

    NekoHTML的核心是两个关键类:`org.cyberneko.html.parsers.DOMParser`和`net.sourceforge.nekodoc.NekoDoc`。`DOMParser`是解析HTML文档的主要类,它基于W3C的Document Object Model (DOM) API来构建解析后的HTML...

    nekohtml-1.9.14源码及jar包

    源码阅读可以帮助开发者了解nekohtml如何处理HTML标签、属性、实体引用等,并可以根据需求进行定制化修改。 **3. 使用nekohtml的关键概念**: - **DOM解析**:nekohtml基于DOM模型解析HTML,将HTML文档转化为一棵...

    NeKoHTML 1.9.21

    总的来说,NeKoHTML 1.9.21是一个强大的工具,可以帮助Java开发者处理和解析HTML文档,无论这些文档是否遵循标准。通过构建规范的DOM树,NeKoHTML简化了复杂HTML数据的处理工作,提升了开发效率和代码质量。

    html解析例子,用nekohtml写的

    要运行这些例子,首先确保你的开发环境中已经安装了Java,并且将`nekohtml.jar`添加到类路径中。然后,你可以通过编译`Neko.java`和`Caipiao.java`生成对应的`.class`文件,最后执行`Caipiao.java`,它会加载并解析`...

    nekohtml-1.9.18_

    3. **文档**:可能包括用户手册、API参考文档和其他帮助资料,帮助开发者了解如何使用NekoHTML。 4. **示例代码**:可能包含一些示例程序,演示了如何在实际项目中集成和使用NekoHTML。 总之,NekoHTML是一个强大的...

    nekohtml-1.9.22.zip

    开发者可以通过这个JAR来查看NekoHTML的所有公开类、接口和方法的详细说明,了解如何使用这些类和方法进行编程。Javadoc是Java的一种标准工具,用于自动生成API文档,帮助开发者理解和使用库。 3. **nekohtml-...

    nekohtml使用笔记 txt

    ### NekoHTML 使用笔记 #### 一、简介与配置 NekoHTML 是一款轻量级且高效的 HTML 解析器库,它可以将不规范的 HTML 文档解析为接近...NekoHTML 作为一款强大的工具,能够帮助开发者轻松应对 HTML 解析的各种挑战。

    上传nekohtml-1.9.9.zip

    在使用"nekohtml-1.9.9.zip"时,你需要将其解压到你的项目中,并通过Java的`import`语句引入相关的类,如`net.sourceforge.nekohtml.NekoHTMLParser`。之后,你可以创建解析器对象并调用其方法来处理HTML字符串或...

    内含httpunit、js、nekohtml、resolver、servlet等多个jar包

    7. **resolver.jar**: 这个文件可能包含了XML解析过程中的资源解析器,帮助处理XML文档中的外部实体引用,如DTD(文档类型定义)或XML Schema。 这些库文件的组合通常出现在Java Web开发的环境中,特别是在构建基于...

    Java parse HTML to XHTML

    在这个名为"Lifedom"的项目或示例中,很可能提供了具体的Java代码来演示上述过程,帮助开发者了解如何在实践中应用NekoHTML进行HTML到XHTML的转换。通过对源代码的分析和学习,我们可以深入理解这一转换过程,并在...

    htmlunit用到的jar包

    2. **nekohtml.jar**:NekoHTML是Xerces-J的一个简化版本,用于解析HTML和XML文档。它帮助HTMLUnit理解不标准或破损的HTML标记,使得HTMLUnit能够处理那些不完全符合规范的网页。 3. **xercesImpl.jar**:Xerces是...

    XSS脚本注入拦截框架 antisamy

    为了帮助完成解析和过滤任务,AntiSamy集成了第三方库Xerces、Batik和NekoHTML。 - **Xerces**:用于XML解析,确保策略文件能够正确解读。 - **Batik**:提供SVG处理能力,对于包含SVG图形的网页而言至关重要。 - *...

    java常用类库中文速查表

    NekoHtml是一个简单的HTML扫描器和标签补偿器,用于解析HTML文档。 HTTP协议支持方面,Apache提供了高效的HTTP客户端编程工具包,支持HTTP协议最新版本。Apache提供了一个基于JavaMailAPI的简化版,用于发送Email的...

    webmagic的所有jar包

    此外,还包含了一些实用工具类和策略类,方便开发者自定义爬虫行为。 3. **webmagic-selenium.jar**:这个jar包引入了Selenium的支持,Selenium是一个自动化测试工具,但在WebMagic中可以用来处理动态加载的内容。...

    HtmlUnit-2.5(jar  doc)

    它详细介绍了库中的类、方法、接口及其用法,帮助开发者快速上手并进行高效的编程。通过查阅API文档,开发者可以学习如何初始化WebClient,如何导航到特定URL,如何处理网页中的JavaScript,以及如何处理异步加载的...

    jeecms 爬虫 1.3 正式版 (附带整合 jeecms2012工程源码)

    这款工具对于开发者来说,能够帮助他们快速地获取和解析Jeecms网站的数据,从而进行数据分析、备份或迁移等操作。 在源码方面,Jeecms 2012工程源码是基于Java开发的内容管理系统,它集成了许多流行的开源组件和...

    Java编写的网页浏览器

    Java中的java.net.URL类可以帮助解析和操作URL。同时,使用java.net.HttpURLConnection或Apache HttpClient库来发送HTTP请求,获取网页内容。 四、HTML解析 加载网页后,浏览器需要解析HTML内容。Java中没有内置的...

Global site tag (gtag.js) - Google Analytics