下面是一个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;
}
}
分享到:
相关推荐
博客链接中提到的是作者Tivonhou在iteye上的博客文章,虽然具体内容无法查看,但通常这类文章可能会涵盖如何使用NekoHtml解析HTML文件、解决常见问题、优化性能,以及与其他解析库对比等方面的知识。 在压缩包...
NekoHTML的核心是两个关键类:`org.cyberneko.html.parsers.DOMParser`和`net.sourceforge.nekodoc.NekoDoc`。`DOMParser`是解析HTML文档的主要类,它基于W3C的Document Object Model (DOM) API来构建解析后的HTML...
源码阅读可以帮助开发者了解nekohtml如何处理HTML标签、属性、实体引用等,并可以根据需求进行定制化修改。 **3. 使用nekohtml的关键概念**: - **DOM解析**:nekohtml基于DOM模型解析HTML,将HTML文档转化为一棵...
总的来说,NeKoHTML 1.9.21是一个强大的工具,可以帮助Java开发者处理和解析HTML文档,无论这些文档是否遵循标准。通过构建规范的DOM树,NeKoHTML简化了复杂HTML数据的处理工作,提升了开发效率和代码质量。
要运行这些例子,首先确保你的开发环境中已经安装了Java,并且将`nekohtml.jar`添加到类路径中。然后,你可以通过编译`Neko.java`和`Caipiao.java`生成对应的`.class`文件,最后执行`Caipiao.java`,它会加载并解析`...
3. **文档**:可能包括用户手册、API参考文档和其他帮助资料,帮助开发者了解如何使用NekoHTML。 4. **示例代码**:可能包含一些示例程序,演示了如何在实际项目中集成和使用NekoHTML。 总之,NekoHTML是一个强大的...
开发者可以通过这个JAR来查看NekoHTML的所有公开类、接口和方法的详细说明,了解如何使用这些类和方法进行编程。Javadoc是Java的一种标准工具,用于自动生成API文档,帮助开发者理解和使用库。 3. **nekohtml-...
### NekoHTML 使用笔记 #### 一、简介与配置 NekoHTML 是一款轻量级且高效的 HTML 解析器库,它可以将不规范的 HTML 文档解析为接近...NekoHTML 作为一款强大的工具,能够帮助开发者轻松应对 HTML 解析的各种挑战。
在使用"nekohtml-1.9.9.zip"时,你需要将其解压到你的项目中,并通过Java的`import`语句引入相关的类,如`net.sourceforge.nekohtml.NekoHTMLParser`。之后,你可以创建解析器对象并调用其方法来处理HTML字符串或...
7. **resolver.jar**: 这个文件可能包含了XML解析过程中的资源解析器,帮助处理XML文档中的外部实体引用,如DTD(文档类型定义)或XML Schema。 这些库文件的组合通常出现在Java Web开发的环境中,特别是在构建基于...
在这个名为"Lifedom"的项目或示例中,很可能提供了具体的Java代码来演示上述过程,帮助开发者了解如何在实践中应用NekoHTML进行HTML到XHTML的转换。通过对源代码的分析和学习,我们可以深入理解这一转换过程,并在...
2. **nekohtml.jar**:NekoHTML是Xerces-J的一个简化版本,用于解析HTML和XML文档。它帮助HTMLUnit理解不标准或破损的HTML标记,使得HTMLUnit能够处理那些不完全符合规范的网页。 3. **xercesImpl.jar**:Xerces是...
为了帮助完成解析和过滤任务,AntiSamy集成了第三方库Xerces、Batik和NekoHTML。 - **Xerces**:用于XML解析,确保策略文件能够正确解读。 - **Batik**:提供SVG处理能力,对于包含SVG图形的网页而言至关重要。 - *...
NekoHtml是一个简单的HTML扫描器和标签补偿器,用于解析HTML文档。 HTTP协议支持方面,Apache提供了高效的HTTP客户端编程工具包,支持HTTP协议最新版本。Apache提供了一个基于JavaMailAPI的简化版,用于发送Email的...
此外,还包含了一些实用工具类和策略类,方便开发者自定义爬虫行为。 3. **webmagic-selenium.jar**:这个jar包引入了Selenium的支持,Selenium是一个自动化测试工具,但在WebMagic中可以用来处理动态加载的内容。...
它详细介绍了库中的类、方法、接口及其用法,帮助开发者快速上手并进行高效的编程。通过查阅API文档,开发者可以学习如何初始化WebClient,如何导航到特定URL,如何处理网页中的JavaScript,以及如何处理异步加载的...
这款工具对于开发者来说,能够帮助他们快速地获取和解析Jeecms网站的数据,从而进行数据分析、备份或迁移等操作。 在源码方面,Jeecms 2012工程源码是基于Java开发的内容管理系统,它集成了许多流行的开源组件和...
Java中的java.net.URL类可以帮助解析和操作URL。同时,使用java.net.HttpURLConnection或Apache HttpClient库来发送HTTP请求,获取网页内容。 四、HTML解析 加载网页后,浏览器需要解析HTML内容。Java中没有内置的...