`
tianhewulei
  • 浏览: 24067 次
  • 性别: 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技术

    NekoHTML技术预研说明,如何进行HTML页面解析,网页信息抽取

    nekohtml-1.9.15.zip

    NekoHTML is written using the Xerces Native Interface (XNI) that is the foundation of the Xerces2 implementation. This enables you to use the NekoHTML parser with existing XNI tools without ...

    NekoHTML

    NULL 博文链接:https://thrillerzw.iteye.com/blog/1924229

    nekohtml-1.9.13.zip

    html解析器nekohtml-1.9.13.zip

    NekoHTML学习笔记.doc

    NekoHTML学习笔记.doc

    NekoHTML学习笔记.rar

    NekoHTML是一个简单地HTML扫描器和标签补偿...NekoHTML能增补缺失的父元素、自动用结束标签关闭相应的元素,以及不匹配的内嵌元素标签。NekoHTML的开发使用了Xerces Native Interface (XNI),后者是Xerces2的实现基础。

    nekohtml解析器

    NekoHTML是一个Java语言的 HTML扫描器和标签补全器(tag balancer) ,使得程序能解析HTML文档并用标准的XML接口来访问其中的信息。这个解析器能够扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档 过程中常...

    NekoHTML的相关用法以及j代码包

    NekoHTML的相关用法以及代码包,以及详细的用法和实例。。。。。

    NeKoHTML 1.9.21

    NeKoHTML:用于java的html编辑。此文件是NeKoHTML V1.9.21版本的Java包合集。

    nekohtml.jar

    nekohtml.jar 解析html的jar包 非常的实用

    nekohtml.jar-nekohtml

    nekohtml.jar nekohtmlSamples.jar

    nekohtml包能够解析HTML文件

    NekoHTML是一个简单地HTML扫描器和标签补偿器(tag balancer) ,使得程序能解析HTML文档并用标准的XML接口来访问其中的信息。这个解析器能投扫描HTML文件并“修正”许多作者(人或机器)在编写HTML文档过程中常犯的...

    nekohtml-1.9.14源码及jar包

    nekohtml-1.9.14源码及jar包

    nekohtml+dom4j

    采用nekohtml补全html到xhtml,结合dom,运用dom4j,支持xpath,强大的网抓工具!

    Java解析HTML之NekoHTML

    NULL 博文链接:https://rensanning.iteye.com/blog/1551831

    nekoHtml 1.9.19 加 source 源码 html分析jar

    nekoHtml 1.9.19 加 source 源码 html分析jar

    nekohtml-1.9.18_

    nekohtml-1.9.18_

    nekohtml-0.9.4.jar

    nekohtml-0.9.4.jar nekohtml-0.9.4.jar nekohtml-0.9.4.jar

    nekohtml-1.9.21.jar

    需要的可以下载这个jar包,不要任何积分哦……

Global site tag (gtag.js) - Google Analytics