Gammo-一个纯Ruby HTML5兼容的解析器

2020-08-17 02:57:21

Gammo提供了一个纯Ruby HTML5兼容的解析器和XPath支持来遍历Gammo构建的DOM树,在Gammo中实现HTML5解析算法符合WHATWG规范。在给定HTML字符串的情况下,Gammo根据WHATWG解析算法中定义的标记化和树构建算法对其进行解析并构建DOM树,这些实现是在没有任何外部依赖的情况下提供的。

甘末,它的名字是受秋葵汤的启发而命名的。但是甘末是用蔬菜做的油炸豆腐。

需要';gammo';需要';open-uri';parser=URI。打开(#39;https://google.com';){|f|Gammo。新建(f.。Read)}文档=解析器。Parse#=>;#<;Gammo::Node::Document>;放置文档。XPath(';//标题';)。首先。INTERN_TEXT#=>;';Google';

解析:Gammo提供了一个解析器,该解析器通过上述标记化和树构造算法实现了解析算法。

Tokenizer在WHATWG中实现了标记化算法。您可以通过调用Gammo::Tokenizer#Next_Token来按顺序获取令牌。

Def dump_for(内标识)放置";数据:#{内标识。数据},类:#{Tok.。Class}";End Tokenizer=Gammo::Tokenizer。令牌化器的新(';<;!doctype html&><;Input type=";button";>;<;frameset>;';)DUMP_。NEXT_TOKEN#=>;数据:HTML,class:Gammo::Tokenizer::DoctypeToken Dump_for Tokenizer。NEXT_TOKEN#=>;DATA:INPUT,class:Gammo::Tokenizer::StartTagToken dump_for tokenizer。Next_Token#=>;data:frameset,class:Gammo::Tokenizer::StartTagToken dump_for tokenizer。NEXT_TOKEN#=>;数据:字符串结尾,类:Gammo::Tokenizer::ErrorToken。

下面描述的解析器依赖于该标记器,它将WHATWG解析算法按顺序应用于通过该标记化提取的标记。

由令牌器生成的令牌将分类为以下类型之一:

成功解析的解析器将文档访问器作为根文档(这与Gammo::Parser#parse的返回值相同)。在文档访问器中,您可以遍历解析器构造的DOM树。

要求';GAMMO';需要';pp&39;文档=GAMMO。新建(';<;!doctype html>;<;输入类型=";button";>;';)。解析def dump_for(node,STRM)STRM<;<;节点。除非节点&;&;(子节点=节点,否则返回_h。FIRST_CHILD)而CHILD DUMP_FOR(CHILD,(STRM.。Last[:Child]||=[])Child=Child。NEXT_SIBLING END STRM END PP DUMP_FOR(文档,[])。

目前,不能像诺基亚那样使用CSS选择器或XPath遍历DOM树,但是Gammo计划在未来实现这些功能。

解析器生成的节点将分为以下类型之一:

对于某些节点(如Gammo::Node::Element和Gammo::Node::Document),它们包含指向可由自身引用的节点的指针,如Gammo::Node#Next_Siering或Gammo::Node#First_Child。此外,还提供了执行DOM生活标准中定义的操作的Gammo::Node#Append_Child和Gammo::Node#Remove_Child等API。

目前,XPath1.0是唯一一种遍历Gammo构建的DOM树的方式。CSS选择器支持也在计划中,但没有任何ETA。

Gammo有一个针对XPath1.0的原始词法分析器/解析器,它在Gammo构建的DOM树中作为帮助器提供。下面是一个简单的示例:

由于这是由Full Scratch实现的,Gammo将提供此支持作为一个非常实验性的功能。如果您发现错误,请提交问题。

在继续详细介绍XPath支持之前,让我们先看几个简单的示例。给出一个示例HTML文本及其DOM树:

文档=Gammo。新建(<;<;-EOS)。Parse<;!DOCTYPE html>;<;html>;<;head>;<;/head>;<;body>;<;h1>;namusyaka.com<;/h1>;<;p class=";description";>;这里是一个示例网站。<;/p>;<;ul。/li&>;<;/ul&>;<;ul id=";>;<;li>;google<;a href=";https://google.com/";>;google.com<;/a>;<;/li>;<;li>;GitHub<;a href=";https://github.com/namusyaka";>;github.com/namusyaka<;/a>;<;/li>;<;/ul>;<;/body>;<;/html>;EOS。

下面的XPath表达式获取具有id=links属性的ul元素下的所有li元素:

下面的XPath表达式获取具有id=links属性的ul元素下每个li元素的每个文本节点:

在与Gammo的组合中,轴说明符指示Gammo构建的DOM树内的导航方向。这是轴的列表。如你所见,Gammo完全支持所有轴。

节点测试由特定的节点名或更通用的表达式组成。虽然像:这样的特定语法应该可以在XPath中指定名称空间前缀,但Gammo还不支持它,因为它不是HTML5中的核心特性。

还要注意,不支持处理指令。目前还没有支持它的计划。

XPath1.0定义了四种数据类型(节点集、字符串、数字、布尔值),并且基于这些类型有各种函数。Gammo部分支持这些功能,请在使用功能前检查是否支持。

正如在开头的功能中提到的,Gammo没有确定其性能的优先级。因此,例如,Gammo不适用于对性能非常敏感的应用程序(例如,根据来自最终用户的传入请求同步执行Gammo解析)。相反,目标是很好地与批处理(如爬虫程序)配合使用。Gammo最优先考虑的是通过不依赖本地扩展和外部gem来执行HTML,从而使其易于解析。

X/net/html:我一直在研究这个包,它给了我实现这一目标的强大理由。