`
zkl_1987
  • 浏览: 245469 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Html parser 代码集锦 1

阅读更多
nekohtml使用笔记

1、透明地创建HTML解析器
  利用Xerces2.0为基础,应用程序通过JAXP实例化解析器对象时,可以透明地创建HTML解析器,此时只需要将NekoHTML的jar文件,在CLASSPATH中放在Xerces的jar文件之前即可。nekohtmlXni.jar中的META-INF/services/org.apache.xerces.xni.parser.XMLParserConfiguration文件会被Xerces的读取并取代标准的设置文件,此处org.apache.xerces.xni.parser.XMLParserConfiguration文件的内容就是一个字符串"org.cyberneko.html.HTMLConfiguration"。这种方法的好处是简单透明,缺点是影响了Xerces在其它情况下的使用。
2、便利的HTML解析器类
  要想避免上述的问题,可以使用org.cyberneko.html.parsers包的DOM和SAX解析器类来创建解析器,这两个类都使用了HTMLConfiguration类。解析器一旦创建之后,就可以解析HTML文件,并用标准的XML接口来访问文件中的信息,就象面对的是一个XML文件一样。

3、文档片段解析
  除了DOM和SAX类,NekoHTML还提供了一个实验性质的DOMFragmentParser类,用以解析HTML文件的片段。我个人认为,由于浏览器的强大的容错能力,即使一个片段的HTML文件,也可以正确显示,由此也变相地造成了很多人不再关心的HTML的完整要求了。这个类,也许将是用的最多的。下面,看看nutch是如何使用nekoHTML的。

package net.nutch.fetcher;   
...   
import org.cyberneko.html.parsers.*;   
import org.xml.sax.*;   
import org.w3c.dom.*;   
import org.w3c.dom.html.*;   
import org.apache.html.dom.*;   
/* A simple fetcher. */  
public class Fetcher {   
....   
   private DOMFragmentParser parser = new DOMFragmentParser();   
....   
   private void handleFetch(URL url, FetchListEntry fle, Http.Response response)   
     throws IOException, SAXException {   
       
     //判断HTTP应答包的类型,只放过html文件   
     String contentType = response.getHeader("Content-Type");   
     if (contentType != null && !contentType.startsWith("text/html"))   
       throw new IOException("Unknown content-type: " + contentType);   
     //创建文件片段对象   
     DocumentFragment node = new HTMLDocumentImpl().createDocumentFragment();   
     //解析HTML内容   
     parser.parse(new InputSource(new ByteArrayInputStream(response.getContent())),node);   
     //取得全部文本内容   
     StringBuffer sb = new StringBuffer();   
     getText(sb, node);   
     String text = sb.toString();   
     //取得标题信息   
     sb.setLength(0);   
     getTitle(sb, node);   
     String title = sb.toString().trim();   
     //取得该页所有的出链   
     ArrayList l = new ArrayList();   
     getOutlinks(url, l, node);   
       
     //显示结果,存储信息   
     Outlink[] outlinks = (Outlink[])l.toArray(new Outlink[l.size()]);   
     LOG.fine("found " + outlinks.length + " outlinks in " + url);   
     outputPage(new FetcherOutput(fle, MD5Hash.digest(response.getContent()),   
                                  true, title, outlinks),   
                new FetcherContent(response.getContent()),   
                new FetcherText(text));   
   }   
  private static void getText(StringBuffer sb, Node node) {   
   if (node.getNodeType() == Node.TEXT_NODE) {   
     sb.append(node.getNodeValue());//取得结点值,即开始与结束标签之间的信息   
   }   
   NodeList children = node.getChildNodes();   
   if ( children != null ) {   
     int len = children.getLength();   
     for ( int i = 0; i < len; i++ ) {   
       getText(sb, children.item(i));//递归遍历DOM树   
     }   
   }   
  }   
  private static boolean getTitle(StringBuffer sb, Node node) {   
   if (node.getNodeType() == Node.ELEMENT_NODE) {   
     if ("title".equalsIgnoreCase(node.getNodeName())) {   
       getText(sb, node);   
       return true;   
     }   
   }   
   NodeList children = node.getChildNodes();   
   if (children != null) {   
     int len = children.getLength();   
     for (int i = 0; i < len; i++) {   
       if (getTitle(sb, children.item(i))) {   
         return true;   
       }   
     }   
   }   
   return false;   
  }   
  private static void getOutlinks(URL base, ArrayList outlinks, Node node) {   
   if (node.getNodeType() == Node.ELEMENT_NODE) {   
     if ("a".equalsIgnoreCase(node.getNodeName())) {   
       StringBuffer linkText = new StringBuffer();   
       getText(linkText, node);   
       NamedNodeMap attrs = node.getAttributes();   
       String target= null;   
       for (int i= 0; i < attrs.getLength(); i++ ) {   
         if ("href".equalsIgnoreCase(attrs.item(i).getNodeName())) {   
           target= attrs.item(i).getNodeValue();//在DOM树中,属性是一个结点。   
           break;   
         }   
       }   
       if (target != null)   
         try {   
           URL url = new URL(base, target);   
           outlinks.add(new Outlink(url.toString(),linkText.toString().trim()));   
         } catch (MalformedURLException e) {   
           // don't care   
         }   
     }   
   }   
   NodeList children = node.getChildNodes();   
   if ( children != null ) {   
     int len = children.getLength();   
     for ( int i = 0; i &lt; len; i++ ) {   
       getOutlinks(base, outlinks, children.item(i));//递归遍历DOM树   
     }   
   }   
  }   
  ....   
}   
  
//注意,此处传递给解析过程parse的文档片段对象,必须是由//org.w3c.dom.html.HTMLDocument类型的DOM文档对象创建,否则有异常。   
//  HTMLConfiguration可以用于创建任何基于XNI解析器,可参考下例   
package sample;   
import org.apache.xerces.parsers.AbstractSAXParser;   
import org.cyberneko.html.HTMLConfiguration;   
public class HTMLSAXParser extends AbstractSAXParser {   
   public HTMLSAXParser() {   
       super(new HTMLConfiguration());   
   }   
}  


三、设置解析器参数
为了更加精确的控制解析的动作,nekohtml提供了相应的设置函数。如下列:
// settings on HTMLConfiguration
org.apache.xerces.xni.parser.XMLParserConfiguration config =
new org.cyberneko.html.HTMLConfiguration();
config.setFeature("http://cyberneko.org/html/features/augmentations", true);
config.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");

// settings on DOMParser
org.cyberneko.html.parsers.DOMParser parser =
new org.cyberneko.html.parsers.DOMParser();
parser.setFeature("http://cyberneko.org/html/features/augmentations", true);
parser.setProperty("http://cyberneko.org/html/properties/names/elems", "lower");

nekohtml功能(feature)列表
功能 默认值 描述
http://cyberneko.org/html/features/balance-tags True 是否允许增补缺失的标签。如果要以XML方式操作HTML文件,此值必须为真。此处提供设置功能,为了性能的原因。
http://cyberneko.org/html/features/balance-tags/ignore-outside-content False 是否忽略文档根元素以后的数据。如果为false,<html>和<bod>被忽略,所有的内容都被解析。
http://cyberneko.org/html/features/document-fragment False 解析HTML片段时是否作标签增补。此功能不要用在DOMParser上,而要用在DOMFragmentParser上。
http://apache.org/xml/features/scanner/notify-char-refs False 当遇到字符实体引用(如&#x20;)是否将(#x20)报告给相应地文档处理器。
http://apache.org/xml/features/scanner/notify-builtin-refs False 当遇到XML内建的字符实体引用(如&amp;)是否将(amp)报告给相应地文档处理器。
http://cyberneko.org/html/features/scanner/notify-builtin-refs False 当遇到HTML内建的字符实体引用(如&copy;)是否将(copy)报告给相应地文档处理器。
http://cyberneko.org/html/features/scanner/script/strip-comment-delims False 是否剥掉<script>元素中的等注释符。
http://cyberneko.org/html/features/augmentations False 是否将与HTML事件有关的infoset项包括在解析管道中。
http://cyberneko.org/html/features/report-errors False 是否报告错误。

nekohtml属性列表
属性 默认值 值域 描述
http://cyberneko.org/html/properties/filters null XMLDocumentFilter[] 在解析管道的最后按数组顺序追加自定义的处理组件(过滤器),必须为数组类型。
http://cyberneko.org/html/properties/default-encoding Windows-1252 IANA encoding names 默认的HTML文件编码
http://cyberneko.org/html/properties/names/elems upper upper,lower,match 如果整理识别出的元素名称
http://cyberneko.org/html/properties/names/attrs lower upper,lower,no-change 如果整理识别出的属性名称

四、管道过滤器

Xerces Native Interface (XNI)定义了一个解析器配置框架,在那儿一个个解析器以模块化组件的形式组成一个管道。这样一来,通过重新安排已有组件和/或新定制开发的组件,就可完成一个新的解析器配置工作。由于nekohtml是采用这个配置框架开发的,所以对解析器新增功能就很简单通过在默认的nekohtml解析管道的末端增加文档过滤器来实现。
要新开发一个过滤器,很简单地实现xerces2的org.apache.xerces.xni.parser包中的 XMLDocumentFilter接口即可。这个接口,一方面使组件成为管道中上一级的事件处理器,另一方面又成为下级的信息源。针对nekohtml 的过滤器开发,只需简单地扩展org.cyberneko.html.filters包中的DefaultFilter类即可。
将自行开发的过滤器加入管道,可参考以下两种办法:
XMLDocumentFilter noop = new DefaultFilter();
XMLDocumentFilter[] filters = { noop };

XMLParserConfiguration parser = new HTMLConfiguration();
parser.setProperty("http://cyberneko.org/html/properties/filters", filters);
nekohtml的org.cyberneko.html.filters 包中有DefaultFilter、
ElementRemover、Identity、Writer,能实现动态插入内容、删除元素、序列化HTML文档等,不详细述。




htmlparser解析自定义标签功能

import org.htmlparser.tags.CompositeTag;    
    
public class StrongTag extends CompositeTag {    
    
    private static final String mIds[] = {    
        "strong"    
    };    
    private static final String mEndTagEnders[] = {    
        "strong"    
    };    
    
    public Strong()    
    {    
    }    
    
    public String[] getIds()    
    {    
        return mIds;    
    }    
    public String[] getEndTagEnders()    
    {    
        return mEndTagEnders;    
    }    
    
}   


上面就是定义这个tag标签继承CompositeTag
然后最重要的是,在使用的时候要注册这个tag

parser = new Parser(url);
PrototypicalNodeFactory p=new PrototypicalNodeFactory();
p.registerTag(new Li());
parser.setNodeFactory(p);
4行代码注册完成,,一个简单的标签自定义完成。



htmlparser获取网页上所有有用链接的方法


public static void getAllLink(String html, String parentUrl) {   
    Parser parser = new Parser();   
    try {   
        parser.setInputHTML(html);   
        NodeFilter filter = new NodeClassFilter(LinkTag.class);   
        NodeList nodes = parser.parse(filter);   
        for (Node node : nodes.toNodeArray()) {   
            LinkTag linkTag = (LinkTag) node;   
            String link = linkTag.getLink().trim();   
            // 过滤,过滤方法可以添加,比如在增加只爬去本域名或本主机名下的网站等等   
            if (!"".equals(link)) {   
                //处理一下那些不是以“http://”开头的url,比如以"/html/....或 html/...."开头的   
                URI uri = new URI(parentUrl);   
                URI _uri = new URI(uri, link);   
                String newUrl = _uri.toString();   
                urls.add(link);   
            }   
        }   
  
    } catch (ParserException e) {   
        throw new RuntimeException("htmlparser解析html文件时异常" + e);   
    } catch (URIException e) {   
        e.printStackTrace();   
    }   
}  




Java 正则表达

\ 反斜杠
\t 间隔 ('\u0009')
\n 换行 ('\u000A')
\r 回车 ('\u000D')
\d 数字 等价于[0-9]
\D 非数字 等价于[^0-9]
\s 空白符号 [\t\n\x0B\f\r]
\S 非空白符号 [^\t\n\x0B\f\r]
\w 单独字符 [a-zA-Z_0-9]
\W 非单独字符 [^a-zA-Z_0-9]
\f 换页符
\e Escape
\b 一个单词的边界
\B 一个非单词的边界
\G 前一个匹配的结束

^为限制开头
^java     条件限制为以Java为开头字符
$为限制结尾
java$     条件限制为以java为结尾字符
.  条件限制除\n以外任意一个单独字符
java..     条件限制为java后除换行外任意两个字符

两者取一「|」
J|A     J或A
Java|Hello     Java或Hello

限制为连续出现指定次数字符「{a}」
J{2}     JJ
J{3}     JJJ

◆文字替换(首次出现字符)
Pattern pattern = Pattern.compile("正则表达式"); 
Matcher matcher = pattern.matcher("正则表达式 Hello World,正则表达式 Hello World"); 
//替换第一个符合正则的数据 
System.out.println(matcher.replaceFirst("Java")); 


◆去除html标记
Pattern pattern = Pattern.compile("<.+?>", Pattern.DOTALL); 
Matcher matcher = pattern.matcher("<a href=\"index.html\">主页</a>"); 
String string = matcher.replaceAll(""); 
System.out.println(string); 




HtmlCleanner结合xpath用法
 HtmlCleaner cleaner = new HtmlCleaner();      
         
      TagNode node = cleaner.clean(new URL("http://finance.sina.com.cn/money/nmetal/20091209/10157077895.shtml"));      
      //按tag取.      
      Object[] ns = node.getElementsByName("title", true);    //标题      
         
      if(ns.length > 0) {      
          System.out.println("title="+((TagNode)ns[0]).getText());      
      }      
      // /html/body/div[2]/div[4]/div/div/div/div[2]/p   
      ns = node.evaluateXPath("//div[@class=\"blkContainerSblkCon\"]/p"); //选取class为指定blkContainerSblkCon的div下面的所有p标签   
      for (int i = 0; i < ns.length; i++) {   
         String in = cleaner.getInnerHtml((TagNode)ns[i]);   
           System.out.println("<p>"+in + "</p>");   
}   
      String in = cleaner.getInnerHtml((TagNode)ns[0]);   
      System.out.println(in);   
  
      System.out.println(((TagNode)ns[0]).getText());   


 HtmlCleaner cleaner = new HtmlCleaner();      
        String url = "http://finance.sina.com.cn/nmetal/hjfx.html";   
        URL _url = new URL(url);   
        TagNode node = cleaner.clean(_url);      
           
        //按tag取.      
        Object[] ns = node.getElementsByName("title", true);    //标题      
           
        if(ns.length > 0) {    
            System.out.println("title="+((TagNode)ns[0]).getText());      
        }     
           
           
        ns = node.evaluateXPath("//*[@class='Frame-Row3-01-C']/table[2]/tbody/tr/td/a"); //选取class为指定blkContainerSblkCon的div下面的所有p   
        for (int i = 0; i < ns.length; i++) {   
               
            //取链接文本   
//           String in = cleaner.getInnerHtml((TagNode)ns[i]);   
//           System.out.println(in);   
               
            //获取链接的   
            TagNode n = (TagNode) ns[i];   
//          System.out.println(n.getAttributeByName("href"));   
            System.out.println(new URL(_url,n.getAttributeByName("href")).toString());   
        }   
//        String in = cleaner.getInnerHtml((TagNode)ns[0]);   
//        System.out.println(in);   
  
//        System.out.println(((TagNode)ns[0]).getText());   
           
//        System.out.println("ul/li:");      
//        //按xpath取      
//        ns = node.evaluateXPath("//div[@class='d_1']//li");      
//        for(Object on : ns) {      
//            TagNode n = (TagNode) on;      
//            System.out.println("\ttext="+n.getText());      
//        }      
//        System.out.println("a:");      
//        //按属性值取      
//        ns = node.getElementsByAttValue("name", "my_href", true, true);      
//        for(Object on : ns) {      
//            TagNode n = (TagNode) on;      
//            System.out.println("\thref="+n.getAttributeByName("href")+", text="+n.getText());      
//        }      


XPath文档:http://www.w3school.com.cn/xpath/xpath_syntax.asp
分享到:
评论
1 楼 di1984HIT 2013-02-14  
集锦内容不错。

相关推荐

    基于JavaParser的代码调用链分析,可以用于分析Java代码的方法调用链.zip

    1. **读取源代码**:使用JavaParser的`JavaSourceParser`解析源代码文件,生成对应的AST。 2. **遍历AST**:遍历AST,寻找`MethodCallExpr`节点,这些节点代表了方法调用。每遇到一个`MethodCallExpr`,提取出被...

    视频编辑MP4 Parser代码与jar包

    《视频编辑MP4 Parser代码与jar包》 MP4 Parser是一种强大的工具,专门用于处理和解析MP4格式的视频文件。MP4(MPEG-4 Part 14)是广泛应用于互联网上的多媒体容器格式,它能包含视频、音频、字幕、图像等多种媒体...

    C++、MFC源代码parser_demo

    【C++与MFC源代码parser_demo解析】 C++是一种通用的编程语言,以其灵活性、高效性和面向对象的特性而闻名。MFC(Microsoft Foundation Classes)是微软为Windows平台开发的应用程序提供的一套C++库,它封装了...

    C++、MFC源代码parser_src

    【标题】"C++、MFC源代码parser_src"是一个关于使用C++编程语言和Microsoft Foundation Class (MFC)库开发解析器的源代码集合。这个项目可能涉及到编译原理和程序设计,其中parser_src可能是指解析器的源代码部分。 ...

    html_parser.zip_Parser_html_html parser_html_parser_zip

    - 搜索和替换HTML代码中的特定字符串。 - 自动化网页测试,模拟用户交互。 在Delphi中使用自定义或第三方HTML解析器时,需要注意兼容性问题,因为不同的HTML语法和浏览器实现可能存在差异。此外,处理异常和错误也...

    HTML-Parser-3.51.rar_html parser_parser perl_perl html

    5. **错误容忍**:HTML-Parser具有良好的错误恢复能力,可以处理不规范的HTML代码。 在实际应用中,`HTML-Parser`常与`LWP::UserAgent`(用于HTTP请求)和`URI`(处理URL)等模块结合,实现网页抓取和自动化数据...

    Python-html5parser一个用于Python基于C的快速HTML5解析

    Python中的`html5-parser`库是一个高效的HTML5解析器,它使用C语言编写,从而提供了比纯Python解析更快的速度。这个库是为了解决在处理大量HTML数据时,需要快速、准确地解析文档的需求。在Python开发中,尤其是在...

    html_parser.rar_Parser_delphi html parser_html parser

    1. **标签识别**:解析器首先需要能够识别HTML文档中的开始标签和结束标签,如`&lt;div&gt;`和`&lt;/div&gt;`,并且区分大小写。 2. **属性解析**:对于每个标签,解析器需要解析其属性,例如`class="container"`,并将其存储为...

    html-parser.js

    对html进行转换,适用爬虫/小程序富文本显示等;对html进行转换,适用爬虫/小程序富文本显示等对html进行转换,适用爬虫/小程序富文本显示等对html进行转换,适用爬虫/小程序富文本显示等

    前端开源库-html-react-parser

    1. **灵活性**:`html-react-parser`允许开发者在解析过程中自定义处理规则,比如通过提供处理器函数来改变特定标签的行为,或者过滤某些不需要的HTML元素。 2. **安全性**:对于传入的HTML字符串,该库会进行适当...

    javaParser 包 javaparser-core-3.6.16.jar

    1. **代码分析**:检查代码质量,找出潜在的 bug,比如未使用的变量、空指针异常等。 2. **代码格式化**:自动格式化代码,使其符合特定的编码规范。 3. **代码重构**:自动进行大规模的代码重构,如重命名变量、...

    enju parser enju parser

    enju parser enju parser

    XMLParser(XML解析代码 C++版)

    XMLParser是一种用于解析XML文档的C++实现,它旨在提供简单、小巧且稳定的解决方案,以处理XML数据。...通过阅读TinyXMLParserSampleCode.pdf提供的示例代码,开发者可以快速掌握如何在实际项目中集成和使用XMLParser。

    前端开源库-html-dom-parser

    3. **错误处理与容错机制**: HTML DOM Parser通常包含良好的错误处理机制,能够处理不完整的HTML代码或非标准语法。这使得在处理来自用户输入或网络抓取的不完美HTML时,库能保持稳定,避免程序崩溃。 4. **API接口...

    gumbo-parser-0.10.1_Parser_

    《gumbo-parser-0.10.1:HTML解析器详解及封装应用》 在Web开发领域,HTML解析器是不可或缺的一部分,它负责将HTML源代码转换为结构化的DOM(Document Object Model)树,便于程序处理和操作。gumbo-parser-0.10.1...

    Laravel开发-php-simple-html-dom-parser

    而"php-simple-html-dom-parser"是一个PHP库,专门用于处理和解析HTML文档,它提供了类似jQuery的API,使得操作HTML文档变得简单直观。这个包的Laravel版本则将这个强大的解析器集成到Laravel框架中,让开发者可以更...

    html-dom-parser:HTML到DOM解析器

    html-dom-parser 在服务器(Node.js)和客户端(浏览器)上均可使用HTML到DOM解析器: HTMLDOMParser(string[, options])解析器将HTML字符串转换为描述DOM树JavaScript对象。例子const parse = require ( '...

    Html_Parser.zip_Parser_java parser

    1. **License.txt**:这个文件通常包含软件的授权协议信息,它规定了用户可以如何使用、修改和分发该库。了解这些信息对于遵循开源社区的规则至关重要,避免在商业项目中引发法律问题。 2. **Readme.txt**:这是一...

    在VS2013下配置Parser Generator1

    VS2013下配置Parser Generator1 Parser Generator是一款功能强大的解析器生成工具,能够帮助开发者快速生成解析器代码。在VS2013环境下配置Parser Generator1需要进行一些设置和配置,本文将详细介绍配置过程。 ...

    jericho html Parser

    1. **错误恢复机制**:jericho HTML Parser具备强大的错误恢复能力,能够处理不完整的标签、缺少的结束标签等常见HTML语法错误。 2. **文档模型**:它提供了一个丰富的文档模型,包括Element、Attribute、Text等类...

Global site tag (gtag.js) - Google Analytics