下面是一个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;
}
}