`
yiminghe
  • 浏览: 1432780 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

write html parser

阅读更多

首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取等处理,这样做的结果很严重

 

Not XHTML Parser

 

另一点需要注意的是:不是构建 xhtml parser ,如果是 xhtml 的话可采用 parser generator 根据 grammar 直接生成解析器即可,而 html 由于对错误很宽容(比如普遍的标签不闭合问题),具备超强的错误纠正机制,简单的自动 parser 生成并不可行。也即 html 不是一种上下文无关 的语言。

 

对 html parser 构建有两个思路:

 

一个思路是半自动生成,先由自动生成的 parser 识别出可以识别的标签,后期再手动匹配标签 ,但这种方法对于本身标签都不完整的情况不能正确识别:

 

<div id='n

 

另一个思路就是完全手写 parser ,递归下降进行 dom 树建立,这其中可以加入很多容错处理,例如 html5 的 parse 规则。

 

Write Parser By Hand

 

手写 parser 从两方面来考虑:

 

1. tag/node 的识别。难点在于 tag 的识别:收集 tag 对应的属性以及属性值。其中词法识别过程可以采用正则表达式来识别标签名,属性名,属性值,不过为了更好的容错以及信息收集,也可以直接采用确定有穷状态机来识别。语法部分就比较简单,将成对的属性名和属性值和标签名关联起来成为 Tag 对象即可。

 

通过 1 可以识别出独立的开标签,闭标签,其他节点元素(text,comment)序列。

 

2. dom 树建立。在该步穿插调用 1 ,将配对的开闭标签组合成为一个 dom 节点。注意点在于

 

   2.1 rawtext/rcdata 的处理:当遇到 textarea ,script,style 时,其后内容的 parse 不能简单的调用 1 步,需要特殊识别对应的结束标记来结束 textarea/syle/script。例如:防止用户输入以下代码意外结束或开始标签(本质上是不符合html5 parse 规范,,规范中说明遇到结束标签会检查下结束标签是不是和当前的开始标签相同,而对 script 即是检查 xx 是不是等于 script (</xx>)):

 

 

<textarea>
 <div>
     x
  </div>
</textarea>
<script>alert("<div></div>");</script>
 

   2.2 标签闭合问题:当遇到结束标签不和当前开始标签相同,或到了parse 结尾时尚有开标签未闭合。例如:

 

 

<div>
<div>
<span>
2
 </div>

 

 

<div>1

 

   这时就需要自动补全闭合标签,对在当前递归分析栈上的开标签元素依次弹出闭合,直到当前结束标签和某个栈上的开标签名称相同或者栈中元素为空。不能匹配的闭标签做抛弃处理。

 

 

  2.3 修正 html 代码(optional)。如果需要对输出代码的质量进行控制(主要指标签嵌套检查),那么就需要在每个节点 parse 完毕后进行修正后处理(post-process),例如:

 

<a href='g.cn'>
 <div>
     1
<span>
3
</span>
<a href='z.cn'>
4
</a>
2
  </div>
</span>
 

修正后的 dom 树对应的 html 为:

 

<div>
     <a href='g.cn'>1
<span>
3
</span>
</a>
<a href='z.cn'>
4
</a>
<a href='g.cn'>
2
</a>
  </div>
 

将嵌套关系错误的元素正确应用到真正需要的对应节点上去。具体对于行内元素 a 包含块状元素 b 的情况,那么该行内元素 a 就需要递归嵌套到块状元素 b 的所有行内元素上去(注意消重)。而对于

 

<div><li>1</li>
<li>2</li>
</div>

 

则需要生成固定的父元素标签 ul:

 

<ul>
	<li>
		1
	</li>
	<li>
		2
	</li>
</ul>
 

 

Scenario

 

常见的应用场景包括: html 代码美化与压缩,高效客户端过滤,规范,检测用户输入的 html (dom-free)。

 

具体到压缩处理 又包含

 

去除默认属性,

合并连续空白,

去除注释,

属性值引号/属性值条件去除,

闭合闭合标签(</body> </html></option> </li>)条件去除

...

 

而这一切都是在 parse 后进行。

 

DEMO

 

html 代码美化与压缩

 

 

分享到:
评论
1 楼 adrift 2011-12-18  
可以采用 jscc 然后加入一些错误恢复代码来处理

相关推荐

    【官方源码】HtmlAgilityPack V1.5.1

    This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don't HAVE to understand XPATH nor XSLT to use it, don't worry...). It is a .NET code library ...

    Html Agility Pack 1.4.6

    This is an agile HTML parser that builds a read/write DOM and supports plain XPATH or XSLT (you actually don't HAVE to understand XPATH nor XSLT to use it, don't worry...). It is a .NET code library ...

    dr-sax:HTML到Markdown转换器,它使用基于sax的解析器(htmlparser2)

    萨克斯博士 Dr. SAX是HTML到Markdown转换器,它使用基于将HTML... write ( '&lt;p&gt;Wow, this is an &lt;b&gt;awesome&lt;/b&gt; HTML parser dude! You should &lt;a&gt;submit it to yahoo!&lt;/a&gt;' ) ; "\n\nWow, this is an **awesome** H

    HttpClient以及获取页面内容应用

    os.write(sc.nextLine()); } } catch (ClientProtocolException e) { e.printStackTrace(); } finally { if (sc != null) { sc.close(); } if (is != null) { is.close(); } if (os != null)...

    NativeXml-master

    Fixed bug with tag parsing where tags like "bla&gt;bla" caused the parser to stop on the "&gt;". Version 2.23 (02Dec2005) ! Fixed bug in entity resolving for attributes ! Bugfix: Take into account ...

    cJSON-master.zip

    That page inspired me to write cJSON, which is a parser that tries to share the same philosophy as JSON itself. Simple, dumb, out of the way. ### Building There are several ways to incorporate ...

    python3.6.5参考手册 chm

    The plistlib module: A Property-List Parser ctypes Enhancements Improved SSL Support Deprecations and Removals Build and C API Changes Port-Specific Changes: Windows Port-Specific Changes: Mac OS...

    Visual C++ 编程资源大全(英文源码 DLL)

    (2KB)&lt;END&gt;&lt;br&gt;87,functionparser.zip A simple yet powerful function parser that parses and evaluates standard mathematical functions (82KB)&lt;END&gt;&lt;br&gt;88,stlxmlparser.zip This is a small non-...

    js使用小技巧

    HTML标签 document.documentElement.innerHTML 第一个style标签 document.styleSheets[0] style标签里的第一个样式 document.styleSheets[0].rules[0] 防止点击空链接时,页面往往重置到页首端。 ()"&gt;word...

    ph-css:Java CSS 2和CSS 3解析器和生成器

    ph-css没有将CSS应用于HTML元素的逻辑。 该页面显示了一些可用于使用该库的基本代码示例。 所有代码段均可免费使用。 ph-css和ph-csscompress-maven-plugin均已获得Apache 2.0许可。 ph-css用作的一部分:) Maven...

    au3反编译源码

    http://www.freewarecorner.de/edecrypt_brute_force_md5_cracker-Download-7298.html Tools ===== 'Regular Expression Renamer' With is you can manually (de)obfuscate function or variable names. ...

    Visual C++ 编程资源大全(英文源码 网络)

    popwatch.zip PopWatch - An application to monitor your POP3 mailbox(17KB)&lt;END&gt;&lt;br&gt;12,server.zip An article about using I/O Completion Ports and Winsock to write robust and scalable Windows ...

    JavaEE 5.0 Tutorial.pdf

    Sun 官方 J2ee 5.0 教程 The Java EE 5Tutorial For Sun Java System Application Server 9.1 Contents Preface ..................................................................................................

Global site tag (gtag.js) - Google Analytics